)]}'
{"keystone/common/sql/contract_repo/versions/024_contract_create_created_at_int_columns.py":[{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"240b956e0babac6618589bd39457dc7a620b1a92","unresolved":false,"context_lines":[{"line_number":11,"context_line":"#    under the License."},{"line_number":12,"context_line":""},{"line_number":13,"context_line":"import datetime"},{"line_number":14,"context_line":"import pytz"},{"line_number":15,"context_line":""},{"line_number":16,"context_line":"import sqlalchemy as sql"},{"line_number":17,"context_line":"from sqlalchemy.orm import sessionmaker"}],"source_content_type":"text/x-python","patch_set":7,"id":"9f436f4f_4ea222fe","line":14,"updated":"2017-08-14 19:27:29.000000000","message":"We don\u0027t appear to have this in our requirements, test or otherwise. It is in global-requirements though [0].\n\nCan we add requirements like this after requirements freeze [1].\n\n[0] https://github.com/openstack/requirements/blob/master/global-requirements.txt#L277\n\n[1] https://releases.openstack.org/pike/schedule.html#p-rf","commit_id":"c696295b5b9e6ae37941184f670f668227dad1a6"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"4d4f0063828b571bb3f4cd88a8233eac0f4faa04","unresolved":false,"context_lines":[{"line_number":11,"context_line":"#    under the License."},{"line_number":12,"context_line":""},{"line_number":13,"context_line":"import datetime"},{"line_number":14,"context_line":"import pytz"},{"line_number":15,"context_line":""},{"line_number":16,"context_line":"import sqlalchemy as sql"},{"line_number":17,"context_line":"from sqlalchemy.orm import sessionmaker"}],"source_content_type":"text/x-python","patch_set":7,"id":"9f436f4f_cd6617c2","line":14,"in_reply_to":"9f436f4f_4ea222fe","updated":"2017-08-14 21:45:52.000000000","message":"Done. I talked to Sean about this in IRC [0].\n\n[0] http://eavesdrop.openstack.org/irclogs/%23openstack-release/%23openstack-release.2017-08-14.log.html#t2017-08-14T20:28:22","commit_id":"c696295b5b9e6ae37941184f670f668227dad1a6"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"240b956e0babac6618589bd39457dc7a620b1a92","unresolved":false,"context_lines":[{"line_number":52,"context_line":"    # The created_at_int data cannot really be nullable long term. This"},{"line_number":53,"context_line":"    # corrects the data to be not nullable, but must be done in the contract"},{"line_number":54,"context_line":"    # phase due to \"additive only\" requirements."},{"line_number":55,"context_line":"    password_table.c.created_at_int.alter(nullable\u003dFalse, default\u003d0,"},{"line_number":56,"context_line":"                                          server_default\u003d\u00270\u0027)"},{"line_number":57,"context_line":"    session.close()"},{"line_number":58,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"9f436f4f_8e2fea3d","line":55,"updated":"2017-08-14 19:27:29.000000000","message":"The only reason we need this here is because we didn\u0027t specify the default in the expand phase of the migration, right? The created_at_int column is already not nullable according to the expand script.","commit_id":"c696295b5b9e6ae37941184f670f668227dad1a6"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"4d4f0063828b571bb3f4cd88a8233eac0f4faa04","unresolved":false,"context_lines":[{"line_number":52,"context_line":"    # The created_at_int data cannot really be nullable long term. This"},{"line_number":53,"context_line":"    # corrects the data to be not nullable, but must be done in the contract"},{"line_number":54,"context_line":"    # phase due to \"additive only\" requirements."},{"line_number":55,"context_line":"    password_table.c.created_at_int.alter(nullable\u003dFalse, default\u003d0,"},{"line_number":56,"context_line":"                                          server_default\u003d\u00270\u0027)"},{"line_number":57,"context_line":"    session.close()"},{"line_number":58,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"9f436f4f_8d5c8fed","line":55,"in_reply_to":"9f436f4f_8e2fea3d","updated":"2017-08-14 21:45:52.000000000","message":"Disregard.","commit_id":"c696295b5b9e6ae37941184f670f668227dad1a6"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"1b7981d2ca01705dc24b318f3924ad08dcae4bc0","unresolved":false,"context_lines":[{"line_number":51,"context_line":"    password_table \u003d sql.Table(\u0027password\u0027, meta, autoload\u003dTrue)"},{"line_number":52,"context_line":"    # The created_at_int data cannot really be nullable long term. This"},{"line_number":53,"context_line":"    # corrects the data to be not nullable, but must be done in the contract"},{"line_number":54,"context_line":"    # phase due to \"additive only\" requirements."},{"line_number":55,"context_line":"    password_table.c.created_at_int.alter(nullable\u003dFalse, default\u003d0,"},{"line_number":56,"context_line":"                                          server_default\u003d\u00270\u0027)"},{"line_number":57,"context_line":"    session.close()"}],"source_content_type":"text/x-python","patch_set":9,"id":"9f436f4f_00028f6f","line":54,"updated":"2017-08-15 16:02:58.000000000","message":"\"additive only\" requirements?\n\nI thought we were doing this in the contract phase because we need to ensure all nodes are running Pike code before we upgrade all the password entries in order to avoid a partial outage?","commit_id":"d57b26cce293f2fbd2aa10b260dfe4d766a9826d"},{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"c74fa330ea10c5e3598e91e1f76e175cf89f3480","unresolved":false,"context_lines":[{"line_number":51,"context_line":"    password_table \u003d sql.Table(\u0027password\u0027, meta, autoload\u003dTrue)"},{"line_number":52,"context_line":"    # The created_at_int data cannot really be nullable long term. This"},{"line_number":53,"context_line":"    # corrects the data to be not nullable, but must be done in the contract"},{"line_number":54,"context_line":"    # phase due to \"additive only\" requirements."},{"line_number":55,"context_line":"    password_table.c.created_at_int.alter(nullable\u003dFalse, default\u003d0,"},{"line_number":56,"context_line":"                                          server_default\u003d\u00270\u0027)"},{"line_number":57,"context_line":"    session.close()"}],"source_content_type":"text/x-python","patch_set":9,"id":"9f436f4f_e380b5f7","line":54,"in_reply_to":"9f436f4f_00028f6f","updated":"2017-08-15 16:07:29.000000000","message":"Both reasons.","commit_id":"d57b26cce293f2fbd2aa10b260dfe4d766a9826d"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"0c4488ae2f080bc60b6076b0ff7e141d09e20377","unresolved":false,"context_lines":[{"line_number":51,"context_line":"    password_table \u003d sql.Table(\u0027password\u0027, meta, autoload\u003dTrue)"},{"line_number":52,"context_line":"    # The created_at_int data cannot really be nullable long term. This"},{"line_number":53,"context_line":"    # corrects the data to be not nullable, but must be done in the contract"},{"line_number":54,"context_line":"    # phase due to \"additive only\" requirements."},{"line_number":55,"context_line":"    password_table.c.created_at_int.alter(nullable\u003dFalse, default\u003d0,"},{"line_number":56,"context_line":"                                          server_default\u003d\u00270\u0027)"},{"line_number":57,"context_line":"    session.close()"}],"source_content_type":"text/x-python","patch_set":9,"id":"9f436f4f_96b7e53a","line":54,"in_reply_to":"9f436f4f_e380b5f7","updated":"2017-08-15 16:29:31.000000000","message":"Done","commit_id":"d57b26cce293f2fbd2aa10b260dfe4d766a9826d"},{"author":{"_account_id":17860,"name":"Samuel de Medeiros Queiroz","email":"samueldmq@gmail.com","username":"samueldmq"},"change_message_id":"5b64f5e4c2adc6dab3b2bf6bbd579051ebcb6198","unresolved":false,"context_lines":[{"line_number":55,"context_line":"    # The second is because we need to ensure all nodes in the deployment are"},{"line_number":56,"context_line":"    # running the Pike code-base before we migrate all password entries. This"},{"line_number":57,"context_line":"    # avoids locking the password table or having a partial outage while doing"},{"line_number":58,"context_line":"    # the migration."},{"line_number":59,"context_line":"    password_table.c.created_at_int.alter(nullable\u003dFalse, default\u003d0,"},{"line_number":60,"context_line":"                                          server_default\u003d\u00270\u0027)"},{"line_number":61,"context_line":"    session.close()"}],"source_content_type":"text/x-python","patch_set":10,"id":"9f436f4f_85ed69b8","line":58,"updated":"2017-08-15 19:57:58.000000000","message":"Nice, this comment clarified a lot of questions I had.","commit_id":"38974af24c47a6c26bb627250657a4d9ed5aa881"}],"keystone/common/sql/core.py":[{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"240b956e0babac6618589bd39457dc7a620b1a92","unresolved":false,"context_lines":[{"line_number":147,"context_line":"            return value"},{"line_number":148,"context_line":"        else:"},{"line_number":149,"context_line":"            if not isinstance(value, datetime.datetime):"},{"line_number":150,"context_line":"                raise ValueError(_(\u0027Programming Error: value to be stored must\u0027"},{"line_number":151,"context_line":"                                   \u0027be a datetime object.\u0027))"},{"line_number":152,"context_line":"            value \u003d timeutils.normalize_time(value)"},{"line_number":153,"context_line":"            value \u003d value.replace(tzinfo\u003dpytz.UTC)"}],"source_content_type":"text/x-python","patch_set":7,"id":"9f436f4f_0e141a43","line":150,"updated":"2017-08-14 19:27:29.000000000","message":"nit: need a space after `must` to avoid:\n\n  Programming Error: value to be stored mustbe a datetime object.","commit_id":"c696295b5b9e6ae37941184f670f668227dad1a6"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"4d4f0063828b571bb3f4cd88a8233eac0f4faa04","unresolved":false,"context_lines":[{"line_number":147,"context_line":"            return value"},{"line_number":148,"context_line":"        else:"},{"line_number":149,"context_line":"            if not isinstance(value, datetime.datetime):"},{"line_number":150,"context_line":"                raise ValueError(_(\u0027Programming Error: value to be stored must\u0027"},{"line_number":151,"context_line":"                                   \u0027be a datetime object.\u0027))"},{"line_number":152,"context_line":"            value \u003d timeutils.normalize_time(value)"},{"line_number":153,"context_line":"            value \u003d value.replace(tzinfo\u003dpytz.UTC)"}],"source_content_type":"text/x-python","patch_set":7,"id":"9f436f4f_8d112f07","line":150,"in_reply_to":"9f436f4f_0e141a43","updated":"2017-08-14 21:45:52.000000000","message":"Done","commit_id":"c696295b5b9e6ae37941184f670f668227dad1a6"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"240b956e0babac6618589bd39457dc7a620b1a92","unresolved":false,"context_lines":[{"line_number":148,"context_line":"        else:"},{"line_number":149,"context_line":"            if not isinstance(value, datetime.datetime):"},{"line_number":150,"context_line":"                raise ValueError(_(\u0027Programming Error: value to be stored must\u0027"},{"line_number":151,"context_line":"                                   \u0027be a datetime object.\u0027))"},{"line_number":152,"context_line":"            value \u003d timeutils.normalize_time(value)"},{"line_number":153,"context_line":"            value \u003d value.replace(tzinfo\u003dpytz.UTC)"},{"line_number":154,"context_line":"            # NOTE(morgan): We are casting this to an int, and ensuring we"}],"source_content_type":"text/x-python","patch_set":7,"id":"9f436f4f_8e292a8b","line":151,"updated":"2017-08-14 19:27:29.000000000","message":"Also - Pike is in stringfreeze. How does this apply to that?","commit_id":"c696295b5b9e6ae37941184f670f668227dad1a6"},{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"dc449eb24f2f7f8c05e363fd9d54129ac573face","unresolved":false,"context_lines":[{"line_number":148,"context_line":"        else:"},{"line_number":149,"context_line":"            if not isinstance(value, datetime.datetime):"},{"line_number":150,"context_line":"                raise ValueError(_(\u0027Programming Error: value to be stored must\u0027"},{"line_number":151,"context_line":"                                   \u0027be a datetime object.\u0027))"},{"line_number":152,"context_line":"            value \u003d timeutils.normalize_time(value)"},{"line_number":153,"context_line":"            value \u003d value.replace(tzinfo\u003dpytz.UTC)"},{"line_number":154,"context_line":"            # NOTE(morgan): We are casting this to an int, and ensuring we"}],"source_content_type":"text/x-python","patch_set":7,"id":"9f436f4f_a9c3c856","line":151,"in_reply_to":"9f436f4f_8e292a8b","updated":"2017-08-14 20:11:17.000000000","message":"*shrug* this is something we have to have, so just send a notification. Usually \"adding\" is less of an issue than \"changing\"","commit_id":"c696295b5b9e6ae37941184f670f668227dad1a6"}],"keystone/common/sql/data_migration_repo/versions/024_migrate_create_created_at_int_columns.py":[{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"b66d73efa0c894c5236ab662d656c1e30efd9e49","unresolved":false,"context_lines":[{"line_number":31,"context_line":"    session \u003d maker()"},{"line_number":32,"context_line":""},{"line_number":33,"context_line":"    password_table \u003d sql.Table(\u0027password\u0027, meta, autoload\u003dTrue)"},{"line_number":34,"context_line":"    passwords \u003d list(password_table.select().execute())"},{"line_number":35,"context_line":""},{"line_number":36,"context_line":"    for passwd in passwords:"},{"line_number":37,"context_line":"        values \u003d {"}],"source_content_type":"text/x-python","patch_set":5,"id":"9f436f4f_177c4a70","line":34,"updated":"2017-08-13 04:43:56.000000000","message":"There isn\u0027t anything to block the update or creation of passwords is there? Thinking abou the case where the expired_at changes during the migration. Or if a new password is created during the migration.","commit_id":"920e146f57e34ab1b533c5f08b7db106881dd176"},{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"01da328d66541e1a3a6c87a1bdfb060061dfbf3d","unresolved":false,"context_lines":[{"line_number":31,"context_line":"    session \u003d maker()"},{"line_number":32,"context_line":""},{"line_number":33,"context_line":"    password_table \u003d sql.Table(\u0027password\u0027, meta, autoload\u003dTrue)"},{"line_number":34,"context_line":"    passwords \u003d list(password_table.select().execute())"},{"line_number":35,"context_line":""},{"line_number":36,"context_line":"    for passwd in passwords:"},{"line_number":37,"context_line":"        values \u003d {"}],"source_content_type":"text/x-python","patch_set":5,"id":"9f436f4f_5da8ac8b","line":34,"in_reply_to":"9f436f4f_177c4a70","updated":"2017-08-14 05:19:01.000000000","message":"Don\u0027t migrate when your nodes are active. There is no good way to manage this without explicitly locking the table. The \"rolling\" upgrade causes a lot of headaches, this is one of them.","commit_id":"920e146f57e34ab1b533c5f08b7db106881dd176"},{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"ef7dda9fe653c40c6a7f35c5c41a747e870e1cfc","unresolved":false,"context_lines":[{"line_number":31,"context_line":"    session \u003d maker()"},{"line_number":32,"context_line":""},{"line_number":33,"context_line":"    password_table \u003d sql.Table(\u0027password\u0027, meta, autoload\u003dTrue)"},{"line_number":34,"context_line":"    passwords \u003d list(password_table.select().execute())"},{"line_number":35,"context_line":""},{"line_number":36,"context_line":"    for passwd in passwords:"},{"line_number":37,"context_line":"        values \u003d {"}],"source_content_type":"text/x-python","patch_set":5,"id":"9f436f4f_1d9c645b","line":34,"in_reply_to":"9f436f4f_5da8ac8b","updated":"2017-08-14 05:22:57.000000000","message":"I guess I could make it a \"while\" loop that keeps looping until no passwords do not have \"created_at_int\" populated. (gross)","commit_id":"920e146f57e34ab1b533c5f08b7db106881dd176"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"240b956e0babac6618589bd39457dc7a620b1a92","unresolved":false,"context_lines":[{"line_number":12,"context_line":""},{"line_number":13,"context_line":""},{"line_number":14,"context_line":"def upgrade(migrate_engine):"},{"line_number":15,"context_line":"    # NO OP"},{"line_number":16,"context_line":"    pass"}],"source_content_type":"text/x-python","patch_set":7,"id":"9f436f4f_ee955688","line":15,"updated":"2017-08-14 19:27:29.000000000","message":"I think we need a big sticker/comment here explaining *why* we can\u0027t do the migration here. Our development process and documentation for operators says that this is the step that does the migration of data, but for this specific case, we\u0027re doing it in the contract phase.\n\nI think justifying it or explaining the reasoning in the comments will help avoid confusion in the future.","commit_id":"c696295b5b9e6ae37941184f670f668227dad1a6"},{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"dc449eb24f2f7f8c05e363fd9d54129ac573face","unresolved":false,"context_lines":[{"line_number":12,"context_line":""},{"line_number":13,"context_line":""},{"line_number":14,"context_line":"def upgrade(migrate_engine):"},{"line_number":15,"context_line":"    # NO OP"},{"line_number":16,"context_line":"    pass"}],"source_content_type":"text/x-python","patch_set":7,"id":"9f436f4f_0996544d","line":15,"in_reply_to":"9f436f4f_ee955688","updated":"2017-08-14 20:11:17.000000000","message":"I disagree, please feel free to add, but this is consistent with other no-op migrates.","commit_id":"c696295b5b9e6ae37941184f670f668227dad1a6"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"1b7981d2ca01705dc24b318f3924ad08dcae4bc0","unresolved":false,"context_lines":[{"line_number":15,"context_line":"    # A migration here is not needed because the actual marshalling of data"},{"line_number":16,"context_line":"    # from the old column to the new column is done in the contract phase. This"},{"line_number":17,"context_line":"    # is because using triggers to convert datetime objects to integers is"},{"line_number":18,"context_line":"    # complex and error-prone. Instead, we\u0027ll migrate the data one all keystone"},{"line_number":19,"context_line":"    # nodes are on the Pike code-base. From an operator perspective, this"},{"line_number":20,"context_line":"    # shouldn\u0027t affect operability of a rolling upgrade since all nodes must be"},{"line_number":21,"context_line":"    # running Pike before the contract takes place."}],"source_content_type":"text/x-python","patch_set":9,"id":"9f436f4f_e0978b47","line":18,"updated":"2017-08-15 16:02:58.000000000","message":"once* (this was probably my spelling mistake)","commit_id":"d57b26cce293f2fbd2aa10b260dfe4d766a9826d"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"0c4488ae2f080bc60b6076b0ff7e141d09e20377","unresolved":false,"context_lines":[{"line_number":15,"context_line":"    # A migration here is not needed because the actual marshalling of data"},{"line_number":16,"context_line":"    # from the old column to the new column is done in the contract phase. This"},{"line_number":17,"context_line":"    # is because using triggers to convert datetime objects to integers is"},{"line_number":18,"context_line":"    # complex and error-prone. Instead, we\u0027ll migrate the data one all keystone"},{"line_number":19,"context_line":"    # nodes are on the Pike code-base. From an operator perspective, this"},{"line_number":20,"context_line":"    # shouldn\u0027t affect operability of a rolling upgrade since all nodes must be"},{"line_number":21,"context_line":"    # running Pike before the contract takes place."}],"source_content_type":"text/x-python","patch_set":9,"id":"9f436f4f_768b6167","line":18,"in_reply_to":"9f436f4f_6392854e","updated":"2017-08-15 16:29:31.000000000","message":"Done","commit_id":"d57b26cce293f2fbd2aa10b260dfe4d766a9826d"},{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"c74fa330ea10c5e3598e91e1f76e175cf89f3480","unresolved":false,"context_lines":[{"line_number":15,"context_line":"    # A migration here is not needed because the actual marshalling of data"},{"line_number":16,"context_line":"    # from the old column to the new column is done in the contract phase. This"},{"line_number":17,"context_line":"    # is because using triggers to convert datetime objects to integers is"},{"line_number":18,"context_line":"    # complex and error-prone. Instead, we\u0027ll migrate the data one all keystone"},{"line_number":19,"context_line":"    # nodes are on the Pike code-base. From an operator perspective, this"},{"line_number":20,"context_line":"    # shouldn\u0027t affect operability of a rolling upgrade since all nodes must be"},{"line_number":21,"context_line":"    # running Pike before the contract takes place."}],"source_content_type":"text/x-python","patch_set":9,"id":"9f436f4f_6392854e","line":18,"in_reply_to":"9f436f4f_e0978b47","updated":"2017-08-15 16:07:29.000000000","message":"Yep! This one was yours. ;) Easy fix though.","commit_id":"d57b26cce293f2fbd2aa10b260dfe4d766a9826d"}],"keystone/common/sql/expand_repo/versions/024_expand_create_created_at_int_columns.py":[{"author":{"_account_id":17860,"name":"Samuel de Medeiros Queiroz","email":"samueldmq@gmail.com","username":"samueldmq"},"change_message_id":"ff925230965b82d1d12c2ff602bc0d119a92f2d6","unresolved":false,"context_lines":[{"line_number":21,"context_line":"    meta.bind \u003d migrate_engine"},{"line_number":22,"context_line":""},{"line_number":23,"context_line":"    # NOTE(morgan): column is nullable here for migration purposes"},{"line_number":24,"context_line":"    # it is set to not-nullalbe in the contract phase to ensure we can handle"},{"line_number":25,"context_line":"    # rolling upgrades in a sane way. This differs from the model in"},{"line_number":26,"context_line":"    # keystone.identity.backends.sql_model by design."},{"line_number":27,"context_line":"    created_at \u003d sql.Column(\u0027created_at_int\u0027, ks_sql.DateTimeInt(),"}],"source_content_type":"text/x-python","patch_set":7,"id":"9f436f4f_732eef92","line":24,"range":{"start_line":24,"start_character":23,"end_line":24,"end_character":31},"updated":"2017-08-14 18:32:04.000000000","message":"nit nullable","commit_id":"c696295b5b9e6ae37941184f670f668227dad1a6"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"4d4f0063828b571bb3f4cd88a8233eac0f4faa04","unresolved":false,"context_lines":[{"line_number":21,"context_line":"    meta.bind \u003d migrate_engine"},{"line_number":22,"context_line":""},{"line_number":23,"context_line":"    # NOTE(morgan): column is nullable here for migration purposes"},{"line_number":24,"context_line":"    # it is set to not-nullalbe in the contract phase to ensure we can handle"},{"line_number":25,"context_line":"    # rolling upgrades in a sane way. This differs from the model in"},{"line_number":26,"context_line":"    # keystone.identity.backends.sql_model by design."},{"line_number":27,"context_line":"    created_at \u003d sql.Column(\u0027created_at_int\u0027, ks_sql.DateTimeInt(),"}],"source_content_type":"text/x-python","patch_set":7,"id":"9f436f4f_4dcea782","line":24,"in_reply_to":"9f436f4f_732eef92","updated":"2017-08-14 21:45:52.000000000","message":"Done","commit_id":"c696295b5b9e6ae37941184f670f668227dad1a6"},{"author":{"_account_id":17860,"name":"Samuel de Medeiros Queiroz","email":"samueldmq@gmail.com","username":"samueldmq"},"change_message_id":"ff925230965b82d1d12c2ff602bc0d119a92f2d6","unresolved":false,"context_lines":[{"line_number":22,"context_line":""},{"line_number":23,"context_line":"    # NOTE(morgan): column is nullable here for migration purposes"},{"line_number":24,"context_line":"    # it is set to not-nullalbe in the contract phase to ensure we can handle"},{"line_number":25,"context_line":"    # rolling upgrades in a sane way. This differs from the model in"},{"line_number":26,"context_line":"    # keystone.identity.backends.sql_model by design."},{"line_number":27,"context_line":"    created_at \u003d sql.Column(\u0027created_at_int\u0027, ks_sql.DateTimeInt(),"},{"line_number":28,"context_line":"                            nullable\u003dTrue)"},{"line_number":29,"context_line":"    expires_at \u003d sql.Column(\u0027expires_at_int\u0027, ks_sql.DateTimeInt(),"}],"source_content_type":"text/x-python","patch_set":7,"id":"9f436f4f_b3445748","line":26,"range":{"start_line":25,"start_character":38,"end_line":26,"end_character":53},"updated":"2017-08-14 18:32:04.000000000","message":"if this differs from the sql model, won\u0027t be there any issues when the code in the server (sqlalchemy will be expecting waht\u0027s in the code) does not match what the database has somewhen between expand - contract in the migration process?","commit_id":"c696295b5b9e6ae37941184f670f668227dad1a6"},{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"aa0eff819b0cd93f424526e3bdaffc285f210d7d","unresolved":false,"context_lines":[{"line_number":22,"context_line":""},{"line_number":23,"context_line":"    # NOTE(morgan): column is nullable here for migration purposes"},{"line_number":24,"context_line":"    # it is set to not-nullalbe in the contract phase to ensure we can handle"},{"line_number":25,"context_line":"    # rolling upgrades in a sane way. This differs from the model in"},{"line_number":26,"context_line":"    # keystone.identity.backends.sql_model by design."},{"line_number":27,"context_line":"    created_at \u003d sql.Column(\u0027created_at_int\u0027, ks_sql.DateTimeInt(),"},{"line_number":28,"context_line":"                            nullable\u003dTrue)"},{"line_number":29,"context_line":"    expires_at \u003d sql.Column(\u0027expires_at_int\u0027, ks_sql.DateTimeInt(),"}],"source_content_type":"text/x-python","patch_set":7,"id":"9f436f4f_336f47fd","line":26,"range":{"start_line":25,"start_character":38,"end_line":26,"end_character":53},"in_reply_to":"9f436f4f_b3445748","updated":"2017-08-14 19:01:57.000000000","message":"Nope, Doesn\u0027t impact anything here. The Model is representative of the way everything should look post contract.","commit_id":"c696295b5b9e6ae37941184f670f668227dad1a6"}],"keystone/identity/backends/sql_model.py":[{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"240b956e0babac6618589bd39457dc7a620b1a92","unresolved":false,"context_lines":[{"line_number":307,"context_line":"    _created_at \u003d sql.Column(\u0027created_at\u0027, sql.DateTime, nullable\u003dFalse,"},{"line_number":308,"context_line":"                             default\u003ddatetime.datetime.utcnow)"},{"line_number":309,"context_line":"    _expires_at \u003d sql.Column(\u0027expires_at\u0027, sql.DateTime, nullable\u003dTrue)"},{"line_number":310,"context_line":"    # set the default to 0, a 0 indicates it is unset."},{"line_number":311,"context_line":"    created_at_int \u003d sql.Column(sql.DateTimeInt(), nullable\u003dFalse,"},{"line_number":312,"context_line":"                                default\u003ddatetime.datetime.utcnow)"},{"line_number":313,"context_line":"    expires_at_int \u003d sql.Column(sql.DateTimeInt(), nullable\u003dTrue)"}],"source_content_type":"text/x-python","patch_set":7,"id":"9f436f4f_0e4c1a40","line":310,"updated":"2017-08-14 19:27:29.000000000","message":"Is the comment here still valid? These definitions aren\u0027t setting defaults.","commit_id":"c696295b5b9e6ae37941184f670f668227dad1a6"},{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"dc449eb24f2f7f8c05e363fd9d54129ac573face","unresolved":false,"context_lines":[{"line_number":307,"context_line":"    _created_at \u003d sql.Column(\u0027created_at\u0027, sql.DateTime, nullable\u003dFalse,"},{"line_number":308,"context_line":"                             default\u003ddatetime.datetime.utcnow)"},{"line_number":309,"context_line":"    _expires_at \u003d sql.Column(\u0027expires_at\u0027, sql.DateTime, nullable\u003dTrue)"},{"line_number":310,"context_line":"    # set the default to 0, a 0 indicates it is unset."},{"line_number":311,"context_line":"    created_at_int \u003d sql.Column(sql.DateTimeInt(), nullable\u003dFalse,"},{"line_number":312,"context_line":"                                default\u003ddatetime.datetime.utcnow)"},{"line_number":313,"context_line":"    expires_at_int \u003d sql.Column(sql.DateTimeInt(), nullable\u003dTrue)"}],"source_content_type":"text/x-python","patch_set":7,"id":"9f436f4f_c99bac70","line":310,"in_reply_to":"9f436f4f_0e4c1a40","updated":"2017-08-14 20:11:17.000000000","message":"somewhat. the default is (server) 0,","commit_id":"c696295b5b9e6ae37941184f670f668227dad1a6"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"240b956e0babac6618589bd39457dc7a620b1a92","unresolved":false,"context_lines":[{"line_number":314,"context_line":"    self_service \u003d sql.Column(sql.Boolean, default\u003dFalse, nullable\u003dFalse,"},{"line_number":315,"context_line":"                              server_default\u003d\u00270\u0027)"},{"line_number":316,"context_line":""},{"line_number":317,"context_line":"    @hybrid_property"},{"line_number":318,"context_line":"    def created_at(self):"},{"line_number":319,"context_line":"        return self.created_at_int or self._created_at"},{"line_number":320,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"9f436f4f_0ede5a6c","line":317,"updated":"2017-08-14 19:27:29.000000000","message":"Does this need to be a hybrid_property? This looks like it\u0027s just comparing attributes of the class.","commit_id":"c696295b5b9e6ae37941184f670f668227dad1a6"},{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"dc449eb24f2f7f8c05e363fd9d54129ac573face","unresolved":false,"context_lines":[{"line_number":314,"context_line":"    self_service \u003d sql.Column(sql.Boolean, default\u003dFalse, nullable\u003dFalse,"},{"line_number":315,"context_line":"                              server_default\u003d\u00270\u0027)"},{"line_number":316,"context_line":""},{"line_number":317,"context_line":"    @hybrid_property"},{"line_number":318,"context_line":"    def created_at(self):"},{"line_number":319,"context_line":"        return self.created_at_int or self._created_at"},{"line_number":320,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"9f436f4f_a9986874","line":317,"in_reply_to":"9f436f4f_0ede5a6c","updated":"2017-08-14 20:11:17.000000000","message":"Not sure. Does it?","commit_id":"c696295b5b9e6ae37941184f670f668227dad1a6"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"1b7981d2ca01705dc24b318f3924ad08dcae4bc0","unresolved":false,"context_lines":[{"line_number":306,"context_line":"    # created_at default set here to safe guard in case it gets missed"},{"line_number":307,"context_line":"    created_at \u003d sql.Column(sql.DateTime, nullable\u003dFalse,"},{"line_number":308,"context_line":"                            default\u003ddatetime.datetime.utcnow)"},{"line_number":309,"context_line":"    expires_at \u003d sql.Column(sql.DateTime, nullable\u003dTrue)"},{"line_number":310,"context_line":"    self_service \u003d sql.Column(sql.Boolean, default\u003dFalse, nullable\u003dFalse,"},{"line_number":311,"context_line":"                              server_default\u003d\u00270\u0027)"},{"line_number":312,"context_line":""}],"source_content_type":"text/x-python","patch_set":9,"id":"9f436f4f_2340fd06","side":"PARENT","line":309,"updated":"2017-08-15 16:02:58.000000000","message":"We can remove these once Rocky opens for development, right? Once migration 24 runs, we should need to keep track of these columns in SQL.","commit_id":"2164d0550c39a07b9c0dacc6c2167d0018b0c7bd"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"0c4488ae2f080bc60b6076b0ff7e141d09e20377","unresolved":false,"context_lines":[{"line_number":306,"context_line":"    # created_at default set here to safe guard in case it gets missed"},{"line_number":307,"context_line":"    created_at \u003d sql.Column(sql.DateTime, nullable\u003dFalse,"},{"line_number":308,"context_line":"                            default\u003ddatetime.datetime.utcnow)"},{"line_number":309,"context_line":"    expires_at \u003d sql.Column(sql.DateTime, nullable\u003dTrue)"},{"line_number":310,"context_line":"    self_service \u003d sql.Column(sql.Boolean, default\u003dFalse, nullable\u003dFalse,"},{"line_number":311,"context_line":"                              server_default\u003d\u00270\u0027)"},{"line_number":312,"context_line":""}],"source_content_type":"text/x-python","patch_set":9,"id":"9f436f4f_16409506","side":"PARENT","line":309,"in_reply_to":"9f436f4f_03ecd98c","updated":"2017-08-15 16:29:31.000000000","message":"Done","commit_id":"2164d0550c39a07b9c0dacc6c2167d0018b0c7bd"},{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"c74fa330ea10c5e3598e91e1f76e175cf89f3480","unresolved":false,"context_lines":[{"line_number":306,"context_line":"    # created_at default set here to safe guard in case it gets missed"},{"line_number":307,"context_line":"    created_at \u003d sql.Column(sql.DateTime, nullable\u003dFalse,"},{"line_number":308,"context_line":"                            default\u003ddatetime.datetime.utcnow)"},{"line_number":309,"context_line":"    expires_at \u003d sql.Column(sql.DateTime, nullable\u003dTrue)"},{"line_number":310,"context_line":"    self_service \u003d sql.Column(sql.Boolean, default\u003dFalse, nullable\u003dFalse,"},{"line_number":311,"context_line":"                              server_default\u003d\u00270\u0027)"},{"line_number":312,"context_line":""}],"source_content_type":"text/x-python","patch_set":9,"id":"9f436f4f_43be61b4","side":"PARENT","line":309,"in_reply_to":"9f436f4f_2340fd06","updated":"2017-08-15 16:07:29.000000000","message":"That is the plan. In R these drop (contract only)","commit_id":"2164d0550c39a07b9c0dacc6c2167d0018b0c7bd"},{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"ba892a9f696f05739ce780bf9cfbabda6bccee29","unresolved":false,"context_lines":[{"line_number":306,"context_line":"    # created_at default set here to safe guard in case it gets missed"},{"line_number":307,"context_line":"    created_at \u003d sql.Column(sql.DateTime, nullable\u003dFalse,"},{"line_number":308,"context_line":"                            default\u003ddatetime.datetime.utcnow)"},{"line_number":309,"context_line":"    expires_at \u003d sql.Column(sql.DateTime, nullable\u003dTrue)"},{"line_number":310,"context_line":"    self_service \u003d sql.Column(sql.Boolean, default\u003dFalse, nullable\u003dFalse,"},{"line_number":311,"context_line":"                              server_default\u003d\u00270\u0027)"},{"line_number":312,"context_line":""}],"source_content_type":"text/x-python","patch_set":9,"id":"9f436f4f_03ecd98c","side":"PARENT","line":309,"in_reply_to":"9f436f4f_235b5d87","updated":"2017-08-15 16:15:26.000000000","message":"No Local changes.","commit_id":"2164d0550c39a07b9c0dacc6c2167d0018b0c7bd"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"b2da3e7df08f9ec141d1e4bfd812ed7e8164d395","unresolved":false,"context_lines":[{"line_number":306,"context_line":"    # created_at default set here to safe guard in case it gets missed"},{"line_number":307,"context_line":"    created_at \u003d sql.Column(sql.DateTime, nullable\u003dFalse,"},{"line_number":308,"context_line":"                            default\u003ddatetime.datetime.utcnow)"},{"line_number":309,"context_line":"    expires_at \u003d sql.Column(sql.DateTime, nullable\u003dTrue)"},{"line_number":310,"context_line":"    self_service \u003d sql.Column(sql.Boolean, default\u003dFalse, nullable\u003dFalse,"},{"line_number":311,"context_line":"                              server_default\u003d\u00270\u0027)"},{"line_number":312,"context_line":""}],"source_content_type":"text/x-python","patch_set":9,"id":"9f436f4f_235b5d87","side":"PARENT","line":309,"in_reply_to":"9f436f4f_43be61b4","updated":"2017-08-15 16:13:51.000000000","message":"Cool - that makes sense. I\u0027d like to have a comment here calling out it\u0027s removal so we don\u0027t forget about it. Want me to add that comment or do you have changes locally?","commit_id":"2164d0550c39a07b9c0dacc6c2167d0018b0c7bd"},{"author":{"_account_id":17860,"name":"Samuel de Medeiros Queiroz","email":"samueldmq@gmail.com","username":"samueldmq"},"change_message_id":"4a1299aeec7aef2cfed9a9fc2a49eb444389879e","unresolved":false,"context_lines":[{"line_number":312,"context_line":"    _created_at \u003d sql.Column(\u0027created_at\u0027, sql.DateTime, nullable\u003dFalse,"},{"line_number":313,"context_line":"                             default\u003ddatetime.datetime.utcnow)"},{"line_number":314,"context_line":"    _expires_at \u003d sql.Column(\u0027expires_at\u0027, sql.DateTime, nullable\u003dTrue)"},{"line_number":315,"context_line":"    # set the default to 0, a 0 indicates it is unset."},{"line_number":316,"context_line":"    created_at_int \u003d sql.Column(sql.DateTimeInt(), nullable\u003dFalse,"},{"line_number":317,"context_line":"                                default\u003ddatetime.datetime.utcnow)"},{"line_number":318,"context_line":"    expires_at_int \u003d sql.Column(sql.DateTimeInt(), nullable\u003dTrue)"}],"source_content_type":"text/x-python","patch_set":10,"id":"9f436f4f_aa75dafb","line":315,"range":{"start_line":315,"start_character":4,"end_line":315,"end_character":54},"updated":"2017-08-15 19:18:18.000000000","message":"don\u0027t create_at_int and expires_at_int need server_default\u003d0 below then?","commit_id":"38974af24c47a6c26bb627250657a4d9ed5aa881"},{"author":{"_account_id":17860,"name":"Samuel de Medeiros Queiroz","email":"samueldmq@gmail.com","username":"samueldmq"},"change_message_id":"5b64f5e4c2adc6dab3b2bf6bbd579051ebcb6198","unresolved":false,"context_lines":[{"line_number":312,"context_line":"    _created_at \u003d sql.Column(\u0027created_at\u0027, sql.DateTime, nullable\u003dFalse,"},{"line_number":313,"context_line":"                             default\u003ddatetime.datetime.utcnow)"},{"line_number":314,"context_line":"    _expires_at \u003d sql.Column(\u0027expires_at\u0027, sql.DateTime, nullable\u003dTrue)"},{"line_number":315,"context_line":"    # set the default to 0, a 0 indicates it is unset."},{"line_number":316,"context_line":"    created_at_int \u003d sql.Column(sql.DateTimeInt(), nullable\u003dFalse,"},{"line_number":317,"context_line":"                                default\u003ddatetime.datetime.utcnow)"},{"line_number":318,"context_line":"    expires_at_int \u003d sql.Column(sql.DateTimeInt(), nullable\u003dTrue)"}],"source_content_type":"text/x-python","patch_set":10,"id":"9f436f4f_059bb965","line":315,"range":{"start_line":315,"start_character":4,"end_line":315,"end_character":54},"in_reply_to":"9f436f4f_aa75dafb","updated":"2017-08-15 19:57:58.000000000","message":"answered in https://review.openstack.org/#/c/493259/7/keystone/identity/backends/sql_model.py\n\nI\u0027d rephrase to \"the default is 0, and 0 indicate...\". set gives the idea it\u0027s setting (explicitly)","commit_id":"38974af24c47a6c26bb627250657a4d9ed5aa881"},{"author":{"_account_id":17860,"name":"Samuel de Medeiros Queiroz","email":"samueldmq@gmail.com","username":"samueldmq"},"change_message_id":"315e6abffd0c252770d4bdf7e4700e2fc517a727","unresolved":false,"context_lines":[{"line_number":321,"context_line":""},{"line_number":322,"context_line":"    @hybrid_property"},{"line_number":323,"context_line":"    def created_at(self):"},{"line_number":324,"context_line":"        return self.created_at_int or self._created_at"},{"line_number":325,"context_line":""},{"line_number":326,"context_line":"    @created_at.setter"},{"line_number":327,"context_line":"    def created_at(self, value):"}],"source_content_type":"text/x-python","patch_set":10,"id":"9f436f4f_e52af5d8","line":324,"range":{"start_line":324,"start_character":35,"end_line":324,"end_character":54},"updated":"2017-08-15 19:59:24.000000000","message":"just for between expand and contract, since self.created_at_int might be None","commit_id":"38974af24c47a6c26bb627250657a4d9ed5aa881"},{"author":{"_account_id":17860,"name":"Samuel de Medeiros Queiroz","email":"samueldmq@gmail.com","username":"samueldmq"},"change_message_id":"315e6abffd0c252770d4bdf7e4700e2fc517a727","unresolved":false,"context_lines":[{"line_number":330,"context_line":""},{"line_number":331,"context_line":"    @hybrid_property"},{"line_number":332,"context_line":"    def expires_at(self):"},{"line_number":333,"context_line":"        return self.expires_at_int or self._expires_at"},{"line_number":334,"context_line":""},{"line_number":335,"context_line":"    @expires_at.setter"},{"line_number":336,"context_line":"    def expires_at(self, value):"}],"source_content_type":"text/x-python","patch_set":10,"id":"9f436f4f_a5206df8","line":333,"range":{"start_line":333,"start_character":15,"end_line":333,"end_character":54},"updated":"2017-08-15 19:59:24.000000000","message":"just for between expand and contract, since self.created_at_int might be None even if self._expires at is not!","commit_id":"38974af24c47a6c26bb627250657a4d9ed5aa881"}],"keystone/tests/unit/test_sql_upgrade.py":[{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"1376c1453cda285f1985ee5ee4fc9a7f5ae4eeb1","unresolved":false,"context_lines":[{"line_number":2399,"context_line":""},{"line_number":2400,"context_line":"        # Test contract phase and ensure data can not be null"},{"line_number":2401,"context_line":"        self.contract(24)"},{"line_number":2402,"context_line":"        password_table.insert().values(password_data).execute()"},{"line_number":2403,"context_line":""},{"line_number":2404,"context_line":""},{"line_number":2405,"context_line":"class MySQLOpportunisticFullMigration(FullMigration):"}],"source_content_type":"text/x-python","patch_set":5,"id":"9f436f4f_7d8c9035","line":2402,"updated":"2017-08-14 05:21:23.000000000","message":"This needs to actually expect an exception and verify the created_at_int cannot be null.","commit_id":"920e146f57e34ab1b533c5f08b7db106881dd176"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"240b956e0babac6618589bd39457dc7a620b1a92","unresolved":false,"context_lines":[{"line_number":2355,"context_line":"        self.assertTableColumns(user_option,"},{"line_number":2356,"context_line":"                                [\u0027user_id\u0027, \u0027option_id\u0027, \u0027option_value\u0027])"},{"line_number":2357,"context_line":""},{"line_number":2358,"context_line":"    def test_migration_024_add_created_expires_at_int_columns_password(self):"},{"line_number":2359,"context_line":"        self.expand(24)"},{"line_number":2360,"context_line":"        self.migrate(23)"},{"line_number":2361,"context_line":"        self.contract(23)"}],"source_content_type":"text/x-python","patch_set":7,"id":"9f436f4f_0ea41aa5","line":2358,"updated":"2017-08-14 19:27:29.000000000","message":"nit: could ensure the columns don\u0027t exist prior to expanding to 24:\n\n  self.expand(23)\n  self.migrate(23)\n  self.contract(23)\n\n  self.assertTableColumns(...)\n\n  self.expand(24)\n\n  self.assertTableColumns(\n      \u0027password\u0027,\n      [\u0027id\u0027, \u0027local_user_id\u0027, \u0027password\u0027, \u0027password_hash\u0027, \u0027created_at\u0027, \u0027created_at_in\u0027,\n       \u0027expires_at\u0027, \u0027expires_at_int\u0027]\n  )\n\n  ...","commit_id":"c696295b5b9e6ae37941184f670f668227dad1a6"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"4d4f0063828b571bb3f4cd88a8233eac0f4faa04","unresolved":false,"context_lines":[{"line_number":2355,"context_line":"        self.assertTableColumns(user_option,"},{"line_number":2356,"context_line":"                                [\u0027user_id\u0027, \u0027option_id\u0027, \u0027option_value\u0027])"},{"line_number":2357,"context_line":""},{"line_number":2358,"context_line":"    def test_migration_024_add_created_expires_at_int_columns_password(self):"},{"line_number":2359,"context_line":"        self.expand(24)"},{"line_number":2360,"context_line":"        self.migrate(23)"},{"line_number":2361,"context_line":"        self.contract(23)"}],"source_content_type":"text/x-python","patch_set":7,"id":"9f436f4f_6dd28b02","line":2358,"in_reply_to":"9f436f4f_0ea41aa5","updated":"2017-08-14 21:45:52.000000000","message":"Done","commit_id":"c696295b5b9e6ae37941184f670f668227dad1a6"}],"releasenotes/notes/password-created-at-stored-as-int-abb59adda73fd78e.yaml":[{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"240b956e0babac6618589bd39457dc7a620b1a92","unresolved":false,"context_lines":[{"line_number":1,"context_line":"---"},{"line_number":2,"context_line":"upgrade:"},{"line_number":3,"context_line":"  - |"},{"line_number":4,"context_line":"    Password created_at field under some versions/deployments of MySQL would"},{"line_number":5,"context_line":"    lose sub-second precision. This means that sometimes (especially in test)"}],"source_content_type":"text/x-yaml","patch_set":7,"id":"9f436f4f_53e40be0","line":2,"updated":"2017-08-14 19:27:29.000000000","message":"bug-1702211 to be consistent with other release notes (and to give readers a link to additional context in the bug report).\n\nhttps://docs.openstack.org/keystone/latest/contributor/release-notes.html","commit_id":"c696295b5b9e6ae37941184f670f668227dad1a6"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"4d4f0063828b571bb3f4cd88a8233eac0f4faa04","unresolved":false,"context_lines":[{"line_number":1,"context_line":"---"},{"line_number":2,"context_line":"upgrade:"},{"line_number":3,"context_line":"  - |"},{"line_number":4,"context_line":"    Password created_at field under some versions/deployments of MySQL would"},{"line_number":5,"context_line":"    lose sub-second precision. This means that sometimes (especially in test)"}],"source_content_type":"text/x-yaml","patch_set":7,"id":"9f436f4f_cd68571e","line":2,"in_reply_to":"9f436f4f_53e40be0","updated":"2017-08-14 21:45:52.000000000","message":"Done","commit_id":"c696295b5b9e6ae37941184f670f668227dad1a6"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"240b956e0babac6618589bd39457dc7a620b1a92","unresolved":false,"context_lines":[{"line_number":1,"context_line":"---"},{"line_number":2,"context_line":"upgrade:"},{"line_number":3,"context_line":"  - |"},{"line_number":4,"context_line":"    Password created_at field under some versions/deployments of MySQL would"},{"line_number":5,"context_line":"    lose sub-second precision. This means that sometimes (especially in test)"},{"line_number":6,"context_line":"    password changes within one second ends where the now active password"},{"line_number":7,"context_line":"    is non-deterministic. This change stores password created_at and"}],"source_content_type":"text/x-yaml","patch_set":7,"id":"9f436f4f_13d20301","line":4,"updated":"2017-08-14 19:27:29.000000000","message":"created_at could be a literal.","commit_id":"c696295b5b9e6ae37941184f670f668227dad1a6"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"4d4f0063828b571bb3f4cd88a8233eac0f4faa04","unresolved":false,"context_lines":[{"line_number":1,"context_line":"---"},{"line_number":2,"context_line":"upgrade:"},{"line_number":3,"context_line":"  - |"},{"line_number":4,"context_line":"    Password created_at field under some versions/deployments of MySQL would"},{"line_number":5,"context_line":"    lose sub-second precision. This means that sometimes (especially in test)"},{"line_number":6,"context_line":"    password changes within one second ends where the now active password"},{"line_number":7,"context_line":"    is non-deterministic. This change stores password created_at and"}],"source_content_type":"text/x-yaml","patch_set":7,"id":"9f436f4f_ed631b41","line":4,"in_reply_to":"9f436f4f_13d20301","updated":"2017-08-14 21:45:52.000000000","message":"Done","commit_id":"c696295b5b9e6ae37941184f670f668227dad1a6"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"240b956e0babac6618589bd39457dc7a620b1a92","unresolved":false,"context_lines":[{"line_number":5,"context_line":"    lose sub-second precision. This means that sometimes (especially in test)"},{"line_number":6,"context_line":"    password changes within one second ends where the now active password"},{"line_number":7,"context_line":"    is non-deterministic. This change stores password created_at and"},{"line_number":8,"context_line":"    expires_at as an integer instead of as a DATETIME data-type."}],"source_content_type":"text/x-yaml","patch_set":7,"id":"9f436f4f_536acbec","line":8,"updated":"2017-08-14 19:27:29.000000000","message":"Same nit here as above.","commit_id":"c696295b5b9e6ae37941184f670f668227dad1a6"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"4d4f0063828b571bb3f4cd88a8233eac0f4faa04","unresolved":false,"context_lines":[{"line_number":5,"context_line":"    lose sub-second precision. This means that sometimes (especially in test)"},{"line_number":6,"context_line":"    password changes within one second ends where the now active password"},{"line_number":7,"context_line":"    is non-deterministic. This change stores password created_at and"},{"line_number":8,"context_line":"    expires_at as an integer instead of as a DATETIME data-type."}],"source_content_type":"text/x-yaml","patch_set":7,"id":"9f436f4f_ad59938e","line":8,"in_reply_to":"9f436f4f_536acbec","updated":"2017-08-14 21:45:52.000000000","message":"Done","commit_id":"c696295b5b9e6ae37941184f670f668227dad1a6"}]}
