)]}'
{"glance/cmd/scrubber.py":[{"author":{"_account_id":5202,"name":"Erno Kuvaja","email":"jokke@usr.fi","username":"jokke"},"change_message_id":"85075c39e209c6d17973f42051a46c6512350ce6","unresolved":false,"context_lines":[{"line_number":38,"context_line":"from glance.common import config"},{"line_number":39,"context_line":"from glance import scrubber"},{"line_number":40,"context_line":""},{"line_number":41,"context_line":"# NOTE(jokke): As per the eventlet commit"},{"line_number":42,"context_line":"# b756447bab51046dfc6f1e0e299cc997ab343701 there\u0027s circular import happening"},{"line_number":43,"context_line":"# which can be solved making sure the hubs are properly and fully imported"},{"line_number":44,"context_line":"# before calling monkey_patch(). This is solved in eventlet 0.22.0 but we"},{"line_number":45,"context_line":"# need to address it before that is widely used around."},{"line_number":46,"context_line":"eventlet.hubs.get_hub()"},{"line_number":47,"context_line":"eventlet.patcher.monkey_patch(all\u003dFalse, socket\u003dTrue, time\u003dTrue, select\u003dTrue,"},{"line_number":48,"context_line":"                              thread\u003dTrue, os\u003dTrue)"},{"line_number":49,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"ff6b8bd7_ae7fefa9","side":"PARENT","line":46,"range":{"start_line":41,"start_character":0,"end_line":46,"end_character":23},"updated":"2018-03-05 10:30:07.000000000","message":"Why removing these? Should not be related.","commit_id":"9df90bd538e8f77b90bc6088c7f9e470d8cbcdad"},{"author":{"_account_id":15054,"name":"wangxiyuan","email":"wangxiyuan1007@gmail.com","username":"wangxiyuan"},"change_message_id":"90d18524664af8fb10da36a454e98dd93460f0ab","unresolved":false,"context_lines":[{"line_number":38,"context_line":"from glance.common import config"},{"line_number":39,"context_line":"from glance import scrubber"},{"line_number":40,"context_line":""},{"line_number":41,"context_line":"# NOTE(jokke): As per the eventlet commit"},{"line_number":42,"context_line":"# b756447bab51046dfc6f1e0e299cc997ab343701 there\u0027s circular import happening"},{"line_number":43,"context_line":"# which can be solved making sure the hubs are properly and fully imported"},{"line_number":44,"context_line":"# before calling monkey_patch(). This is solved in eventlet 0.22.0 but we"},{"line_number":45,"context_line":"# need to address it before that is widely used around."},{"line_number":46,"context_line":"eventlet.hubs.get_hub()"},{"line_number":47,"context_line":"eventlet.patcher.monkey_patch(all\u003dFalse, socket\u003dTrue, time\u003dTrue, select\u003dTrue,"},{"line_number":48,"context_line":"                              thread\u003dTrue, os\u003dTrue)"},{"line_number":49,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"ff6b8bd7_0eedadee","side":"PARENT","line":46,"range":{"start_line":41,"start_character":0,"end_line":46,"end_character":23},"in_reply_to":"ff6b8bd7_ae7fefa9","updated":"2018-03-06 03:09:13.000000000","message":"Ops, I\u0027m not sure why it\u0027s removed. I\u0027ll add them back.","commit_id":"9df90bd538e8f77b90bc6088c7f9e470d8cbcdad"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"7d584c3dfb45013ebeb57650155f20fb628d0dda","unresolved":false,"context_lines":[{"line_number":78,"context_line":"            # 2. Try to check the process name."},{"line_number":79,"context_line":"            error_str \u003d (\"ERROR: The glance-scrubber process is running under \""},{"line_number":80,"context_line":"                         \"daemon. Please stop it first.\")"},{"line_number":81,"context_line":"            pid_file \u003d \u0027/var/run/glance/glance-scrubber.pid\u0027"},{"line_number":82,"context_line":"            if os.path.exists(os.path.abspath(pid_file)):"},{"line_number":83,"context_line":"                sys.exit(error_str)"},{"line_number":84,"context_line":"            for glance_scrubber_name in [\u0027glance-scrubber\u0027,"}],"source_content_type":"text/x-python","patch_set":9,"id":"df7087c5_3d30c507","line":81,"range":{"start_line":81,"start_character":23,"end_line":81,"end_character":60},"updated":"2018-03-20 07:35:04.000000000","message":"will this always the same path across different os.\n\nI strongly feel that we should only consider checking by the process name only.","commit_id":"1cf5c90594df8f3be2ce57666f289e4c5f056bcd"},{"author":{"_account_id":15054,"name":"wangxiyuan","email":"wangxiyuan1007@gmail.com","username":"wangxiyuan"},"change_message_id":"a20f18c2e58dcd3fcf4854477008c6f87c70d82e","unresolved":false,"context_lines":[{"line_number":78,"context_line":"            # 2. Try to check the process name."},{"line_number":79,"context_line":"            error_str \u003d (\"ERROR: The glance-scrubber process is running under \""},{"line_number":80,"context_line":"                         \"daemon. Please stop it first.\")"},{"line_number":81,"context_line":"            pid_file \u003d \u0027/var/run/glance/glance-scrubber.pid\u0027"},{"line_number":82,"context_line":"            if os.path.exists(os.path.abspath(pid_file)):"},{"line_number":83,"context_line":"                sys.exit(error_str)"},{"line_number":84,"context_line":"            for glance_scrubber_name in [\u0027glance-scrubber\u0027,"}],"source_content_type":"text/x-python","patch_set":9,"id":"df7087c5_16303b07","line":81,"range":{"start_line":81,"start_character":23,"end_line":81,"end_character":60},"in_reply_to":"df7087c5_3d30c507","updated":"2018-03-20 12:27:54.000000000","message":"I\u0027m not sure.\nActually I just copied it from glance-control. This is just a double check. If guys don\u0027t like it. I can remove then.","commit_id":"1cf5c90594df8f3be2ce57666f289e4c5f056bcd"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"7d584c3dfb45013ebeb57650155f20fb628d0dda","unresolved":false,"context_lines":[{"line_number":83,"context_line":"                sys.exit(error_str)"},{"line_number":84,"context_line":"            for glance_scrubber_name in [\u0027glance-scrubber\u0027,"},{"line_number":85,"context_line":"                                         \u0027glance.cmd.scrubber\u0027]:"},{"line_number":86,"context_line":"                cmd \u003d subprocess.Popen("},{"line_number":87,"context_line":"                    [\u0027/usr/bin/pgrep\u0027, \u0027-f\u0027, glance_scrubber_name],"},{"line_number":88,"context_line":"                    stdout\u003dsubprocess.PIPE, shell\u003dFalse)"},{"line_number":89,"context_line":"                pids, _ \u003d cmd.communicate()"},{"line_number":90,"context_line":"                self_pid \u003d os.getpid()"}],"source_content_type":"text/x-python","patch_set":9,"id":"df7087c5_9d2a318e","line":87,"range":{"start_line":86,"start_character":16,"end_line":87,"end_character":66},"updated":"2018-03-20 07:35:04.000000000","message":"I guess its better to use oslo.rootwrap module but we need to add it in the requirements.txt. (Need another core\u0027s opinion though)\n[1] https://github.com/openstack/oslo.rootwrap/blob/master/oslo_rootwrap/wrapper.py#L212","commit_id":"1cf5c90594df8f3be2ce57666f289e4c5f056bcd"},{"author":{"_account_id":15054,"name":"wangxiyuan","email":"wangxiyuan1007@gmail.com","username":"wangxiyuan"},"change_message_id":"a20f18c2e58dcd3fcf4854477008c6f87c70d82e","unresolved":false,"context_lines":[{"line_number":83,"context_line":"                sys.exit(error_str)"},{"line_number":84,"context_line":"            for glance_scrubber_name in [\u0027glance-scrubber\u0027,"},{"line_number":85,"context_line":"                                         \u0027glance.cmd.scrubber\u0027]:"},{"line_number":86,"context_line":"                cmd \u003d subprocess.Popen("},{"line_number":87,"context_line":"                    [\u0027/usr/bin/pgrep\u0027, \u0027-f\u0027, glance_scrubber_name],"},{"line_number":88,"context_line":"                    stdout\u003dsubprocess.PIPE, shell\u003dFalse)"},{"line_number":89,"context_line":"                pids, _ \u003d cmd.communicate()"},{"line_number":90,"context_line":"                self_pid \u003d os.getpid()"}],"source_content_type":"text/x-python","patch_set":9,"id":"df7087c5_36677f28","line":87,"range":{"start_line":86,"start_character":16,"end_line":87,"end_character":66},"in_reply_to":"df7087c5_9d2a318e","updated":"2018-03-20 12:27:54.000000000","message":"I agree with you that use root is better, but pgrep can be used by every users by default, and introduce oslo.rootwrap or oslo.privsep seems not a small work. Do we have to do it?","commit_id":"1cf5c90594df8f3be2ce57666f289e4c5f056bcd"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"57a518a60943fc4844d2817b794de23741a20691","unresolved":false,"context_lines":[{"line_number":98,"context_line":"                    sys.exit(error_str)"},{"line_number":99,"context_line":"                elif pids.count(\u0027\\n\u0027) \u003e 0 and str(self_pid) not in pids:"},{"line_number":100,"context_line":"                    # If self is not in result and the pids number \u003e0, it means"},{"line_number":101,"context_line":"                    # that the glance-scrubber is running under daemon."},{"line_number":102,"context_line":"                    sys.exit(error_str)"},{"line_number":103,"context_line":"            app.revert_image_status(CONF.restore)"},{"line_number":104,"context_line":"        elif CONF.daemon:"}],"source_content_type":"text/x-python","patch_set":13,"id":"9f6a8fd7_f7d6d327","line":101,"range":{"start_line":101,"start_character":30,"end_line":101,"end_character":71},"updated":"2018-04-18 10:33:05.000000000","message":"at line #97 you are saying that it is running as daemon and here as well same thing.\n\nI guess one check should be intended for scrubber is running as non-daemon?","commit_id":"17eab5b1f4758867d06e5a2e634ce75d08392fd6"},{"author":{"_account_id":15054,"name":"wangxiyuan","email":"wangxiyuan1007@gmail.com","username":"wangxiyuan"},"change_message_id":"774137eeedcd05b0296b6b61450a2b78b1dd1d94","unresolved":false,"context_lines":[{"line_number":98,"context_line":"                    sys.exit(error_str)"},{"line_number":99,"context_line":"                elif pids.count(\u0027\\n\u0027) \u003e 0 and str(self_pid) not in pids:"},{"line_number":100,"context_line":"                    # If self is not in result and the pids number \u003e0, it means"},{"line_number":101,"context_line":"                    # that the glance-scrubber is running under daemon."},{"line_number":102,"context_line":"                    sys.exit(error_str)"},{"line_number":103,"context_line":"            app.revert_image_status(CONF.restore)"},{"line_number":104,"context_line":"        elif CONF.daemon:"}],"source_content_type":"text/x-python","patch_set":13,"id":"9f6a8fd7_c113ba5b","line":101,"range":{"start_line":101,"start_character":30,"end_line":101,"end_character":71},"in_reply_to":"9f6a8fd7_9283e5cc","updated":"2018-04-19 02:57:12.000000000","message":"yeah, Erno is correct.\n\nMy comment here is a little wrong. Actually no matter the \"glance-scrubber\" is running under daemon or not, this check in L95-L101 always works. It just checks the process name.\n\nI\u0027ll update the comment to avoid the misleading.","commit_id":"17eab5b1f4758867d06e5a2e634ce75d08392fd6"},{"author":{"_account_id":5202,"name":"Erno Kuvaja","email":"jokke@usr.fi","username":"jokke"},"change_message_id":"5283d83d03dcb7dbfac9e12e3366e885852b9abe","unresolved":false,"context_lines":[{"line_number":98,"context_line":"                    sys.exit(error_str)"},{"line_number":99,"context_line":"                elif pids.count(\u0027\\n\u0027) \u003e 0 and str(self_pid) not in pids:"},{"line_number":100,"context_line":"                    # If self is not in result and the pids number \u003e0, it means"},{"line_number":101,"context_line":"                    # that the glance-scrubber is running under daemon."},{"line_number":102,"context_line":"                    sys.exit(error_str)"},{"line_number":103,"context_line":"            app.revert_image_status(CONF.restore)"},{"line_number":104,"context_line":"        elif CONF.daemon:"}],"source_content_type":"text/x-python","patch_set":13,"id":"9f6a8fd7_9283e5cc","line":101,"range":{"start_line":101,"start_character":30,"end_line":101,"end_character":71},"in_reply_to":"9f6a8fd7_f7d6d327","updated":"2018-04-18 11:22:30.000000000","message":"So I\u0027m not sure if this is relevant situation to take into account, but as it is implemented the comment is correct. The previous one checks if there is at minimum 2 pids which of one is the processes own pid and this block checks if there is at least one pid even if the process itself is not in the list.","commit_id":"17eab5b1f4758867d06e5a2e634ce75d08392fd6"}],"glance/db/sqlalchemy/api.py":[{"author":{"_account_id":27248,"name":"Prateek Goel","email":"prateek.goel2@tatacommunications.com","username":"prateek.goel"},"change_message_id":"092293b40db87ee140d97cb531ab63a7d93d81e8","unresolved":false,"context_lines":[{"line_number":168,"context_line":""},{"line_number":169,"context_line":"    session \u003d get_session()"},{"line_number":170,"context_line":"    with session.begin():"},{"line_number":171,"context_line":"        image_ref \u003d _image_get(context, image_id, session\u003dsession)"},{"line_number":172,"context_line":""},{"line_number":173,"context_line":"        query \u003d session.query(models.Image).filter_by("},{"line_number":174,"context_line":"            id\u003dimage_id).filter_by(status\u003d\u0027pending_delete\u0027)"},{"line_number":175,"context_line":"        values \u003d {\u0027status\u0027: \u0027active\u0027, \u0027deleted\u0027: 0}"},{"line_number":176,"context_line":"        updated \u003d query.update(values, synchronize_session\u003d\u0027fetch\u0027)"},{"line_number":177,"context_line":""},{"line_number":178,"context_line":"        if not updated:"},{"line_number":179,"context_line":"            msg \u003d (_(\u0027cannot restore the image from %s to active (wanted \u0027"},{"line_number":180,"context_line":"                     \u0027from_state\u003dpending_delete)\u0027) % image_ref.status)"},{"line_number":181,"context_line":"            raise exception.Conflict(msg)"},{"line_number":182,"context_line":""},{"line_number":183,"context_line":""},{"line_number":184,"context_line":"@retry(retry_on_exception\u003d_retry_on_deadlock, wait_fixed\u003d500,"}],"source_content_type":"text/x-python","patch_set":6,"id":"df7087c5_e3684222","line":181,"range":{"start_line":171,"start_character":8,"end_line":181,"end_character":41},"updated":"2018-03-11 18:22:10.000000000","message":"I feel, when we fetch the image_ref, we can check its status\u003dpending_delete if, not return error/raise exception otherwise proceed. Additionally, since we our query is status\u003dpending_delete, I don\u0027t think we will have \"if not updated\" issue at line #178 due to state transition error..hence I feel the exception could also be altered...","commit_id":"af99754c308a5fd1bee28f335fdb9b8dc860a52c"},{"author":{"_account_id":27248,"name":"Prateek Goel","email":"prateek.goel2@tatacommunications.com","username":"prateek.goel"},"change_message_id":"e12b7be9a7670c486cc43e865ad96a2018cab67c","unresolved":false,"context_lines":[{"line_number":168,"context_line":""},{"line_number":169,"context_line":"    session \u003d get_session()"},{"line_number":170,"context_line":"    with session.begin():"},{"line_number":171,"context_line":"        image_ref \u003d _image_get(context, image_id, session\u003dsession)"},{"line_number":172,"context_line":""},{"line_number":173,"context_line":"        query \u003d session.query(models.Image).filter_by("},{"line_number":174,"context_line":"            id\u003dimage_id).filter_by(status\u003d\u0027pending_delete\u0027)"},{"line_number":175,"context_line":"        values \u003d {\u0027status\u0027: \u0027active\u0027, \u0027deleted\u0027: 0}"},{"line_number":176,"context_line":"        updated \u003d query.update(values, synchronize_session\u003d\u0027fetch\u0027)"},{"line_number":177,"context_line":""},{"line_number":178,"context_line":"        if not updated:"},{"line_number":179,"context_line":"            msg \u003d (_(\u0027cannot restore the image from %s to active (wanted \u0027"},{"line_number":180,"context_line":"                     \u0027from_state\u003dpending_delete)\u0027) % image_ref.status)"},{"line_number":181,"context_line":"            raise exception.Conflict(msg)"},{"line_number":182,"context_line":""},{"line_number":183,"context_line":""},{"line_number":184,"context_line":"@retry(retry_on_exception\u003d_retry_on_deadlock, wait_fixed\u003d500,"}],"source_content_type":"text/x-python","patch_set":6,"id":"df7087c5_d81b897e","line":181,"range":{"start_line":171,"start_character":8,"end_line":181,"end_character":41},"in_reply_to":"df7087c5_d28b6a1c","updated":"2018-03-13 04:44:30.000000000","message":"Yes, the code would work correct, however, I am looking at an optimization. We already have the image_ref with which we can check its status. If its status is not pending_delete we can error/raise exception there itself else we can call query.update. Now if, query.update fails it means it is for some other reason and can raise an appropriate exception.","commit_id":"af99754c308a5fd1bee28f335fdb9b8dc860a52c"},{"author":{"_account_id":15054,"name":"wangxiyuan","email":"wangxiyuan1007@gmail.com","username":"wangxiyuan"},"change_message_id":"87cbda7b88211ea36a612a569bddb90709f886a9","unresolved":false,"context_lines":[{"line_number":168,"context_line":""},{"line_number":169,"context_line":"    session \u003d get_session()"},{"line_number":170,"context_line":"    with session.begin():"},{"line_number":171,"context_line":"        image_ref \u003d _image_get(context, image_id, session\u003dsession)"},{"line_number":172,"context_line":""},{"line_number":173,"context_line":"        query \u003d session.query(models.Image).filter_by("},{"line_number":174,"context_line":"            id\u003dimage_id).filter_by(status\u003d\u0027pending_delete\u0027)"},{"line_number":175,"context_line":"        values \u003d {\u0027status\u0027: \u0027active\u0027, \u0027deleted\u0027: 0}"},{"line_number":176,"context_line":"        updated \u003d query.update(values, synchronize_session\u003d\u0027fetch\u0027)"},{"line_number":177,"context_line":""},{"line_number":178,"context_line":"        if not updated:"},{"line_number":179,"context_line":"            msg \u003d (_(\u0027cannot restore the image from %s to active (wanted \u0027"},{"line_number":180,"context_line":"                     \u0027from_state\u003dpending_delete)\u0027) % image_ref.status)"},{"line_number":181,"context_line":"            raise exception.Conflict(msg)"},{"line_number":182,"context_line":""},{"line_number":183,"context_line":""},{"line_number":184,"context_line":"@retry(retry_on_exception\u003d_retry_on_deadlock, wait_fixed\u003d500,"}],"source_content_type":"text/x-python","patch_set":6,"id":"df7087c5_d28b6a1c","line":181,"range":{"start_line":171,"start_character":8,"end_line":181,"end_character":41},"in_reply_to":"df7087c5_e3684222","updated":"2018-03-13 02:20:22.000000000","message":"I think the code works correct. L171 ensure the image exist and L173 to check if it\u0027s pending_delete, if not, the query will be None and \u0027updated\u0027 will be None of cause. I added two test for it in the new patch set to ensure it works. Please take a look. Thanks.","commit_id":"af99754c308a5fd1bee28f335fdb9b8dc860a52c"}],"glance/scrubber.py":[{"author":{"_account_id":5202,"name":"Erno Kuvaja","email":"jokke@usr.fi","username":"jokke"},"change_message_id":"85075c39e209c6d17973f42051a46c6512350ce6","unresolved":false,"context_lines":[{"line_number":388,"context_line":"            raise"},{"line_number":389,"context_line":""},{"line_number":390,"context_line":"    def revert_image_status(self, image_id):"},{"line_number":391,"context_line":"        db_api.get_api().image_update(self.admin_context, image_id,"},{"line_number":392,"context_line":"                                      {\u0027status\u0027: \u0027active\u0027},"},{"line_number":393,"context_line":"                                      from_state\u003d\u0027pending_delete\u0027)"}],"source_content_type":"text/x-python","patch_set":2,"id":"ff6b8bd7_8903050e","line":393,"range":{"start_line":391,"start_character":0,"end_line":393,"end_character":66},"updated":"2018-03-05 10:30:07.000000000","message":"For this to work you need to add the \u0027active\u0027 to valid state from pending_delete in to domain/__init__.py L:110","commit_id":"f1a52c34fc51fbe5b7d96160391bf53051df429c"},{"author":{"_account_id":15054,"name":"wangxiyuan","email":"wangxiyuan1007@gmail.com","username":"wangxiyuan"},"change_message_id":"90d18524664af8fb10da36a454e98dd93460f0ab","unresolved":false,"context_lines":[{"line_number":388,"context_line":"            raise"},{"line_number":389,"context_line":""},{"line_number":390,"context_line":"    def revert_image_status(self, image_id):"},{"line_number":391,"context_line":"        db_api.get_api().image_update(self.admin_context, image_id,"},{"line_number":392,"context_line":"                                      {\u0027status\u0027: \u0027active\u0027},"},{"line_number":393,"context_line":"                                      from_state\u003d\u0027pending_delete\u0027)"}],"source_content_type":"text/x-python","patch_set":2,"id":"ff6b8bd7_31dc9473","line":393,"range":{"start_line":391,"start_character":0,"end_line":393,"end_character":66},"in_reply_to":"ff6b8bd7_8903050e","updated":"2018-03-06 03:09:13.000000000","message":"Done","commit_id":"f1a52c34fc51fbe5b7d96160391bf53051df429c"}],"glance/tests/functional/test_scrubber.py":[{"author":{"_account_id":5202,"name":"Erno Kuvaja","email":"jokke@usr.fi","username":"jokke"},"change_message_id":"6b9be6b8cd4586cd9c0815be17a45dbbe7eac0e0","unresolved":false,"context_lines":[{"line_number":306,"context_line":"        self.start_servers(delayed_delete\u003dTrue, daemon\u003dFalse,"},{"line_number":307,"context_line":"                           metadata_encryption_key\u003d\u0027\u0027)"},{"line_number":308,"context_line":""},{"line_number":309,"context_line":"        path \u003d \"http://%s:%d/v1/images\" % (\"127.0.0.1\", self.api_port)"},{"line_number":310,"context_line":"        response, content \u003d self._send_http_request(path, \u0027POST\u0027, body\u003d\u0027XXX\u0027)"},{"line_number":311,"context_line":"        self.assertEqual(http_client.CREATED, response.status)"},{"line_number":312,"context_line":"        image \u003d jsonutils.loads(content)[\u0027image\u0027]"}],"source_content_type":"text/x-python","patch_set":4,"id":"ff6b8bd7_25ff67ab","line":309,"range":{"start_line":309,"start_character":29,"end_line":309,"end_character":31},"updated":"2018-03-06 11:41:55.000000000","message":"No, no and one more time no. Images API v1 is deprecated for removal in this cycle, so we definitely do not want a single test more that will break when we do so.","commit_id":"98463fb65ad94fa3a67b688a84ef89fcd71bc186"},{"author":{"_account_id":15054,"name":"wangxiyuan","email":"wangxiyuan1007@gmail.com","username":"wangxiyuan"},"change_message_id":"d6c4771c12529886b7e3e0416a0d007afbb0f338","unresolved":false,"context_lines":[{"line_number":306,"context_line":"        self.start_servers(delayed_delete\u003dTrue, daemon\u003dFalse,"},{"line_number":307,"context_line":"                           metadata_encryption_key\u003d\u0027\u0027)"},{"line_number":308,"context_line":""},{"line_number":309,"context_line":"        path \u003d \"http://%s:%d/v1/images\" % (\"127.0.0.1\", self.api_port)"},{"line_number":310,"context_line":"        response, content \u003d self._send_http_request(path, \u0027POST\u0027, body\u003d\u0027XXX\u0027)"},{"line_number":311,"context_line":"        self.assertEqual(http_client.CREATED, response.status)"},{"line_number":312,"context_line":"        image \u003d jsonutils.loads(content)[\u0027image\u0027]"}],"source_content_type":"text/x-python","patch_set":4,"id":"ff6b8bd7_a587f7d7","line":309,"range":{"start_line":309,"start_character":29,"end_line":309,"end_character":31},"in_reply_to":"ff6b8bd7_25ff67ab","updated":"2018-03-06 11:59:54.000000000","message":"the test refactor patch is here:\nhttps://review.openstack.org/#/c/550025/\nI\u0027ll rebase this patch on it later.","commit_id":"98463fb65ad94fa3a67b688a84ef89fcd71bc186"},{"author":{"_account_id":5202,"name":"Erno Kuvaja","email":"jokke@usr.fi","username":"jokke"},"change_message_id":"6b9be6b8cd4586cd9c0815be17a45dbbe7eac0e0","unresolved":false,"context_lines":[{"line_number":312,"context_line":"        image \u003d jsonutils.loads(content)[\u0027image\u0027]"},{"line_number":313,"context_line":"        self.assertEqual(\u0027active\u0027, image[\u0027status\u0027])"},{"line_number":314,"context_line":""},{"line_number":315,"context_line":"        path \u003d \"http://%s:%d/v1/images/%s\" % (\"127.0.0.1\", self.api_port,"},{"line_number":316,"context_line":"                                              image[\u0027id\u0027])"},{"line_number":317,"context_line":"        response, content \u003d self._send_http_request(path, \u0027DELETE\u0027)"},{"line_number":318,"context_line":"        self.assertEqual(http_client.OK, response.status)"}],"source_content_type":"text/x-python","patch_set":4,"id":"ff6b8bd7_c52d4b47","line":315,"range":{"start_line":315,"start_character":29,"end_line":315,"end_character":31},"updated":"2018-03-06 11:41:55.000000000","message":"ditto","commit_id":"98463fb65ad94fa3a67b688a84ef89fcd71bc186"}]}
