)]}'
{"doc/notification_samples/instance-update-tags-action.json":[{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"fc8629da26fb5638e9d9cb3ae52d9dc20eb5b12a","unresolved":false,"context_lines":[{"line_number":34,"context_line":"            \"task_state\": \"scheduling\","},{"line_number":35,"context_line":"            \"power_state\": \"pending\","},{"line_number":36,"context_line":"            \"ip_addresses\": [],"},{"line_number":37,"context_line":"            \"state_update\": {"},{"line_number":38,"context_line":"                \"nova_object.data\": {"},{"line_number":39,"context_line":"                    \"new_task_state\": null,"},{"line_number":40,"context_line":"                    \"old_state\": \"active\","},{"line_number":41,"context_line":"                    \"old_task_state\": null,"},{"line_number":42,"context_line":"                    \"state\": \"active\"},"},{"line_number":43,"context_line":"                \"nova_object.name\": \"InstanceStateUpdatePayload\","},{"line_number":44,"context_line":"                \"nova_object.namespace\": \"nova\","},{"line_number":45,"context_line":"                \"nova_object.version\": \"1.0\"},"},{"line_number":46,"context_line":"            \"tenant_id\": \"6f70656e737461636b20342065766572\","},{"line_number":47,"context_line":"            \"terminated_at\": null,"},{"line_number":48,"context_line":"            \"auto_disk_config\":\"MANUAL\","}],"source_content_type":"application/json","patch_set":17,"id":"ff0f0b1f_c9335df6","line":45,"range":{"start_line":37,"start_character":12,"end_line":45,"end_character":46},"updated":"2017-05-25 17:25:22.000000000","message":"I\u0027m not sure why this is in here, but I think this is wrong.","commit_id":"9d2ebbbc2d4dd542327d5d9ae0a32fdcb2ac976e"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"33c108a8fa693fc0d7487fd2f23471ab291a8e13","unresolved":false,"context_lines":[{"line_number":68,"context_line":"            \"reservation_id\": \"r-53ad660s\","},{"line_number":69,"context_line":"            \"state\": \"active\","},{"line_number":70,"context_line":"            \"state_update\": {"},{"line_number":71,"context_line":"                \"nova_object.data\": {"},{"line_number":72,"context_line":"                    \"new_task_state\": null,"},{"line_number":73,"context_line":"                    \"old_state\": \"active\","},{"line_number":74,"context_line":"                    \"old_task_state\": null,"},{"line_number":75,"context_line":"                    \"state\": \"active\"},"},{"line_number":76,"context_line":"                \"nova_object.name\": \"InstanceStateUpdatePayload\","},{"line_number":77,"context_line":"                \"nova_object.namespace\": \"nova\","},{"line_number":78,"context_line":"                \"nova_object.version\": \"1.0\"},"}],"source_content_type":"application/json","patch_set":21,"id":"df140735_4d41bda8","line":75,"range":{"start_line":71,"start_character":16,"end_line":75,"end_character":39},"updated":"2017-06-05 21:37:04.000000000","message":"I still think this is confusing, but unless we make the state_update field nullable\u003dTrue we don\u0027t really have a way around this and we just have to assume/hope consumers understand that if the fields are the same there was no state change.","commit_id":"4c868e265a2a826433bd603d28115e1eed4e9520"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"606a7a9f271d6e9ca6d194a76bd83a29d5653313","unresolved":false,"context_lines":[{"line_number":72,"context_line":"                    \"new_task_state\": null,"},{"line_number":73,"context_line":"                    \"old_state\": \"active\","},{"line_number":74,"context_line":"                    \"old_task_state\": null,"},{"line_number":75,"context_line":"                    \"state\": \"active\"},"},{"line_number":76,"context_line":"                \"nova_object.name\": \"InstanceStateUpdatePayload\","},{"line_number":77,"context_line":"                \"nova_object.namespace\": \"nova\","},{"line_number":78,"context_line":"                \"nova_object.version\": \"1.0\"},"}],"source_content_type":"application/json","patch_set":23,"id":"df140735_9df6cc5c","line":75,"updated":"2017-06-06 15:14:26.000000000","message":"I think it is not a big confusion to have the old and the new state as \u0027active\u0027. I\u0027m pretty sure that the legacy notification works the same way so consumers already understands this. I don\u0027t see precedence where we send null for an unchanged value. The null value of new_task_state indicates that there is no task running on the instance.","commit_id":"ba75127c8c5084f8c13c5d4a01dd65d99c83f00f"}],"nova/api/openstack/compute/server_tags.py":[{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"79fc883b7fddfc4a214ecec1406a72b60c4afd17","unresolved":false,"context_lines":[{"line_number":53,"context_line":"        super(ServerTagsController, self).__init__()"},{"line_number":54,"context_line":""},{"line_number":55,"context_line":"    def _check_instance_in_valid_state(self, context, server_id, action):"},{"line_number":56,"context_line":"        instance \u003d common.get_instance(self.compute_api, context, server_id)"},{"line_number":57,"context_line":"        if instance.vm_state not in (vm_states.ACTIVE, vm_states.PAUSED,"},{"line_number":58,"context_line":"                                     vm_states.SUSPENDED, vm_states.STOPPED):"},{"line_number":59,"context_line":"            exc \u003d exception.InstanceInvalidState(attr\u003d\u0027vm_state\u0027,"}],"source_content_type":"text/x-python","patch_set":7,"id":"ff0f0b1f_d8cdd466","line":56,"updated":"2017-05-23 02:25:12.000000000","message":"Can we please return the instance we got there so we don\u0027t have to look it up again later to send the notification?","commit_id":"c537ef443ae111f3a881b034e668ac9c49d49caa"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"79fc883b7fddfc4a214ecec1406a72b60c4afd17","unresolved":false,"context_lines":[{"line_number":141,"context_line":"        try:"},{"line_number":142,"context_line":"            with nova_context.target_cell(context, im.cell_mapping):"},{"line_number":143,"context_line":"                tag.create()"},{"line_number":144,"context_line":"            instance \u003d common.get_instance(self.compute_api, context,"},{"line_number":145,"context_line":"                                           server_id)"},{"line_number":146,"context_line":"        except exception.InstanceNotFound as e:"},{"line_number":147,"context_line":"            raise webob.exc.HTTPNotFound(explanation\u003de.format_message())"}],"source_content_type":"text/x-python","patch_set":7,"id":"ff0f0b1f_98d87c1e","line":144,"updated":"2017-05-23 02:25:12.000000000","message":"See my comment above, let\u0027s only get this once please.\n\nOr does this not work because we need a fresh copy of the instance to get the updated tags?\n\nRather than pull the full instance again, couldn\u0027t we just refresh the tags on the instance we got before? instance.refresh() should do that, but even that is a bit heavy. Seems we should be able to get the TagList for the instance uuid and store that on our already-retrieved instance, or just set the tag variable in scope on the object. I\u0027d really just like to avoid another call to the database here, especially since we might not even be sending notifications.","commit_id":"c537ef443ae111f3a881b034e668ac9c49d49caa"},{"author":{"_account_id":15888,"name":"Zhenyu Zheng","email":"zheng.zhenyu@outlook.com","username":"Kevin_Zheng"},"change_message_id":"b15359f92928998c71b07329f993a09e662f1d1f","unresolved":false,"context_lines":[{"line_number":141,"context_line":"        try:"},{"line_number":142,"context_line":"            with nova_context.target_cell(context, im.cell_mapping):"},{"line_number":143,"context_line":"                tag.create()"},{"line_number":144,"context_line":"            instance \u003d common.get_instance(self.compute_api, context,"},{"line_number":145,"context_line":"                                           server_id)"},{"line_number":146,"context_line":"        except exception.InstanceNotFound as e:"},{"line_number":147,"context_line":"            raise webob.exc.HTTPNotFound(explanation\u003de.format_message())"}],"source_content_type":"text/x-python","patch_set":7,"id":"ff0f0b1f_734a69ac","line":144,"in_reply_to":"ff0f0b1f_98d87c1e","updated":"2017-05-23 03:15:10.000000000","message":"Thanks, yeah, I think your idea is better.","commit_id":"c537ef443ae111f3a881b034e668ac9c49d49caa"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"79fc883b7fddfc4a214ecec1406a72b60c4afd17","unresolved":false,"context_lines":[{"line_number":146,"context_line":"        except exception.InstanceNotFound as e:"},{"line_number":147,"context_line":"            raise webob.exc.HTTPNotFound(explanation\u003de.format_message())"},{"line_number":148,"context_line":""},{"line_number":149,"context_line":"        notifications.base.send_update(context, instance, instance)"},{"line_number":150,"context_line":""},{"line_number":151,"context_line":"        response \u003d webob.Response(status_int\u003d201)"},{"line_number":152,"context_line":"        response.headers[\u0027Location\u0027] \u003d self._view_builder.get_location("}],"source_content_type":"text/x-python","patch_set":7,"id":"ff0f0b1f_781c88c0","line":149,"range":{"start_line":149,"start_character":48,"end_line":149,"end_character":66},"updated":"2017-05-23 02:25:12.000000000","message":"This looks weird. Normally this is used when updating an instance via instance.save() but we\u0027re not doing that with tags, so we\u0027re just kind of using this as a crutch to send the notification we care about. I guess that might be OK because it eventually goes through _send_instance_update_notification and shouldn\u0027t be sending anything about vm or task state changes, but we might want to leave a comment about re-using this method.","commit_id":"c537ef443ae111f3a881b034e668ac9c49d49caa"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"79fc883b7fddfc4a214ecec1406a72b60c4afd17","unresolved":false,"context_lines":[{"line_number":146,"context_line":"        except exception.InstanceNotFound as e:"},{"line_number":147,"context_line":"            raise webob.exc.HTTPNotFound(explanation\u003de.format_message())"},{"line_number":148,"context_line":""},{"line_number":149,"context_line":"        notifications.base.send_update(context, instance, instance)"},{"line_number":150,"context_line":""},{"line_number":151,"context_line":"        response \u003d webob.Response(status_int\u003d201)"},{"line_number":152,"context_line":"        response.headers[\u0027Location\u0027] \u003d self._view_builder.get_location("}],"source_content_type":"text/x-python","patch_set":7,"id":"ff0f0b1f_78eec8b4","line":149,"range":{"start_line":149,"start_character":8,"end_line":149,"end_character":26},"updated":"2017-05-23 02:25:12.000000000","message":"nit: please import like this:\n\nfrom nova.notifications import base as notifications_base\n\nOr something similar. We don\u0027t usually do the package chaining like this.","commit_id":"c537ef443ae111f3a881b034e668ac9c49d49caa"},{"author":{"_account_id":15888,"name":"Zhenyu Zheng","email":"zheng.zhenyu@outlook.com","username":"Kevin_Zheng"},"change_message_id":"b15359f92928998c71b07329f993a09e662f1d1f","unresolved":false,"context_lines":[{"line_number":146,"context_line":"        except exception.InstanceNotFound as e:"},{"line_number":147,"context_line":"            raise webob.exc.HTTPNotFound(explanation\u003de.format_message())"},{"line_number":148,"context_line":""},{"line_number":149,"context_line":"        notifications.base.send_update(context, instance, instance)"},{"line_number":150,"context_line":""},{"line_number":151,"context_line":"        response \u003d webob.Response(status_int\u003d201)"},{"line_number":152,"context_line":"        response.headers[\u0027Location\u0027] \u003d self._view_builder.get_location("}],"source_content_type":"text/x-python","patch_set":7,"id":"ff0f0b1f_f35e7974","line":149,"range":{"start_line":149,"start_character":48,"end_line":149,"end_character":66},"in_reply_to":"ff0f0b1f_781c88c0","updated":"2017-05-23 03:15:10.000000000","message":"Done","commit_id":"c537ef443ae111f3a881b034e668ac9c49d49caa"},{"author":{"_account_id":15888,"name":"Zhenyu Zheng","email":"zheng.zhenyu@outlook.com","username":"Kevin_Zheng"},"change_message_id":"b15359f92928998c71b07329f993a09e662f1d1f","unresolved":false,"context_lines":[{"line_number":146,"context_line":"        except exception.InstanceNotFound as e:"},{"line_number":147,"context_line":"            raise webob.exc.HTTPNotFound(explanation\u003de.format_message())"},{"line_number":148,"context_line":""},{"line_number":149,"context_line":"        notifications.base.send_update(context, instance, instance)"},{"line_number":150,"context_line":""},{"line_number":151,"context_line":"        response \u003d webob.Response(status_int\u003d201)"},{"line_number":152,"context_line":"        response.headers[\u0027Location\u0027] \u003d self._view_builder.get_location("}],"source_content_type":"text/x-python","patch_set":7,"id":"ff0f0b1f_d357f557","line":149,"range":{"start_line":149,"start_character":8,"end_line":149,"end_character":26},"in_reply_to":"ff0f0b1f_78eec8b4","updated":"2017-05-23 03:15:10.000000000","message":"Done","commit_id":"c537ef443ae111f3a881b034e668ac9c49d49caa"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"79fc883b7fddfc4a214ecec1406a72b60c4afd17","unresolved":false,"context_lines":[{"line_number":168,"context_line":"        try:"},{"line_number":169,"context_line":"            with nova_context.target_cell(context, im.cell_mapping):"},{"line_number":170,"context_line":"                tags \u003d objects.TagList.create(context, server_id, body[\u0027tags\u0027])"},{"line_number":171,"context_line":"            instance \u003d common.get_instance(self.compute_api, context,"},{"line_number":172,"context_line":"                                           server_id)"},{"line_number":173,"context_line":"        except exception.InstanceNotFound as e:"},{"line_number":174,"context_line":"            raise webob.exc.HTTPNotFound(explanation\u003de.format_message())"},{"line_number":175,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"ff0f0b1f_38ce102e","line":172,"range":{"start_line":171,"start_character":12,"end_line":172,"end_character":53},"updated":"2017-05-23 02:25:12.000000000","message":"same as above, why can\u0027t we just do:\n\ninstance \u003d self._check_instance_in_valid_state(...)\n\n...\n\ninstance.tags \u003d tags\nnotifications.send_update(context, instance, instance)","commit_id":"c537ef443ae111f3a881b034e668ac9c49d49caa"},{"author":{"_account_id":15888,"name":"Zhenyu Zheng","email":"zheng.zhenyu@outlook.com","username":"Kevin_Zheng"},"change_message_id":"b15359f92928998c71b07329f993a09e662f1d1f","unresolved":false,"context_lines":[{"line_number":168,"context_line":"        try:"},{"line_number":169,"context_line":"            with nova_context.target_cell(context, im.cell_mapping):"},{"line_number":170,"context_line":"                tags \u003d objects.TagList.create(context, server_id, body[\u0027tags\u0027])"},{"line_number":171,"context_line":"            instance \u003d common.get_instance(self.compute_api, context,"},{"line_number":172,"context_line":"                                           server_id)"},{"line_number":173,"context_line":"        except exception.InstanceNotFound as e:"},{"line_number":174,"context_line":"            raise webob.exc.HTTPNotFound(explanation\u003de.format_message())"},{"line_number":175,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"ff0f0b1f_f3d319d4","line":172,"range":{"start_line":171,"start_character":12,"end_line":172,"end_character":53},"in_reply_to":"ff0f0b1f_38ce102e","updated":"2017-05-23 03:15:10.000000000","message":"Done","commit_id":"c537ef443ae111f3a881b034e668ac9c49d49caa"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"a8c700acc8dd30b2c0a1fd595116c80f19e31aad","unresolved":false,"context_lines":[{"line_number":147,"context_line":"            raise webob.exc.HTTPNotFound(explanation\u003de.format_message())"},{"line_number":148,"context_line":""},{"line_number":149,"context_line":"        # re-using the send_update method normally used for instance.save()"},{"line_number":150,"context_line":"        notifications_base.send_update(context, instance, instance)"},{"line_number":151,"context_line":""},{"line_number":152,"context_line":"        response \u003d webob.Response(status_int\u003d201)"},{"line_number":153,"context_line":"        response.headers[\u0027Location\u0027] \u003d self._view_builder.get_location("}],"source_content_type":"text/x-python","patch_set":12,"id":"ff0f0b1f_ae65e81f","line":150,"range":{"start_line":150,"start_character":27,"end_line":150,"end_character":38},"updated":"2017-05-25 02:09:09.000000000","message":"As we discussed in IRC, I don\u0027t think we should be using this, it\u0027s not meant for how it\u0027s used (sending the same instance). Plus it\u0027s setting the publisher as \u0027compute\u0027 when it should be \u0027nova-api\u0027 to match the flavor and aggregate versioned notifications.","commit_id":"3522d24f813eecd77bd4255e477ea78294aa12c5"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"33c108a8fa693fc0d7487fd2f23471ab291a8e13","unresolved":false,"context_lines":[{"line_number":214,"context_line":"        try:"},{"line_number":215,"context_line":"            with nova_context.target_cell(context, im.cell_mapping) as cctxt:"},{"line_number":216,"context_line":"                objects.TagList.destroy(cctxt, server_id)"},{"line_number":217,"context_line":"                instance.tags \u003d objects.TagList.get_by_resource_id(cctxt,"},{"line_number":218,"context_line":"                                                                   server_id)"},{"line_number":219,"context_line":"        except exception.InstanceNotFound as e:"},{"line_number":220,"context_line":"            raise webob.exc.HTTPNotFound(explanation\u003de.format_message())"},{"line_number":221,"context_line":""}],"source_content_type":"text/x-python","patch_set":21,"id":"df140735_ed4891b3","line":218,"range":{"start_line":217,"start_character":16,"end_line":218,"end_character":77},"updated":"2017-06-05 21:37:04.000000000","message":"If we deleted all tags, couldn\u0027t we avoid the DB API call by just doing:\n\n  instance.tags \u003d objects.TagList()\n\n?","commit_id":"4c868e265a2a826433bd603d28115e1eed4e9520"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"606a7a9f271d6e9ca6d194a76bd83a29d5653313","unresolved":false,"context_lines":[{"line_number":108,"context_line":"        im \u003d _get_instance_mapping(context, server_id)"},{"line_number":109,"context_line":""},{"line_number":110,"context_line":"        with nova_context.target_cell(context, im.cell_mapping) as cctxt:"},{"line_number":111,"context_line":"            instance \u003d self._check_instance_in_valid_state("},{"line_number":112,"context_line":"                cctxt, server_id, \u0027update tag\u0027)"},{"line_number":113,"context_line":""},{"line_number":114,"context_line":"        try:"}],"source_content_type":"text/x-python","patch_set":23,"id":"df140735_1d6e3cff","line":111,"range":{"start_line":111,"start_character":12,"end_line":111,"end_character":58},"updated":"2017-06-06 15:14:26.000000000","message":"nit: this reads more naturally if we rename the function to something like _get_instance_in_valid_state\nHowever I won\u0027t hold up this patch due to this.","commit_id":"ba75127c8c5084f8c13c5d4a01dd65d99c83f00f"}],"nova/notifications/base.py":[{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"fc8629da26fb5638e9d9cb3ae52d9dc20eb5b12a","unresolved":false,"context_lines":[{"line_number":226,"context_line":""},{"line_number":227,"context_line":"    payload \u003d info_from_instance(context, instance, None, None)"},{"line_number":228,"context_line":""},{"line_number":229,"context_line":"    # determine how we\u0027ll report states"},{"line_number":230,"context_line":"    payload.update("},{"line_number":231,"context_line":"        _compute_states_payload("},{"line_number":232,"context_line":"            instance, old_vm_state, old_task_state,"},{"line_number":233,"context_line":"            new_vm_state, new_task_state))"},{"line_number":234,"context_line":""},{"line_number":235,"context_line":"    # add audit fields:"},{"line_number":236,"context_line":"    (audit_start, audit_end) \u003d audit_period_bounds(current_period\u003dTrue)"}],"source_content_type":"text/x-python","patch_set":17,"id":"ff0f0b1f_496e2dca","line":233,"range":{"start_line":229,"start_character":4,"end_line":233,"end_character":42},"updated":"2017-05-25 17:25:22.000000000","message":"Oh I see, this is why. We should pass a kwarg to send_instance_update_notification to toggle whether or not we send this, and make it send them by default, but the server tags controller API code can tell it not to.","commit_id":"9d2ebbbc2d4dd542327d5d9ae0a32fdcb2ac976e"},{"author":{"_account_id":15888,"name":"Zhenyu Zheng","email":"zheng.zhenyu@outlook.com","username":"Kevin_Zheng"},"change_message_id":"5ca1f62015d567feea67b85caad7359af420836d","unresolved":false,"context_lines":[{"line_number":226,"context_line":""},{"line_number":227,"context_line":"    payload \u003d info_from_instance(context, instance, None, None)"},{"line_number":228,"context_line":""},{"line_number":229,"context_line":"    # determine how we\u0027ll report states"},{"line_number":230,"context_line":"    payload.update("},{"line_number":231,"context_line":"        _compute_states_payload("},{"line_number":232,"context_line":"            instance, old_vm_state, old_task_state,"},{"line_number":233,"context_line":"            new_vm_state, new_task_state))"},{"line_number":234,"context_line":""},{"line_number":235,"context_line":"    # add audit fields:"},{"line_number":236,"context_line":"    (audit_start, audit_end) \u003d audit_period_bounds(current_period\u003dTrue)"}],"source_content_type":"text/x-python","patch_set":17,"id":"ff0f0b1f_71030c75","line":233,"range":{"start_line":229,"start_character":4,"end_line":233,"end_character":42},"in_reply_to":"ff0f0b1f_46704fdd","updated":"2017-05-26 02:48:12.000000000","message":"Thinking again, we are actually sending InstanceUpdatePayload obj here and InstanceStateUpdatePayload is one part of the obj, so I guess we have to still send it here.\nhttp://git.openstack.org/cgit/openstack/nova/tree/nova/notifications/objects/instance.py#n168","commit_id":"9d2ebbbc2d4dd542327d5d9ae0a32fdcb2ac976e"},{"author":{"_account_id":15888,"name":"Zhenyu Zheng","email":"zheng.zhenyu@outlook.com","username":"Kevin_Zheng"},"change_message_id":"94ad0f326916d8d1540db15dd0e06ecda16250ef","unresolved":false,"context_lines":[{"line_number":226,"context_line":""},{"line_number":227,"context_line":"    payload \u003d info_from_instance(context, instance, None, None)"},{"line_number":228,"context_line":""},{"line_number":229,"context_line":"    # determine how we\u0027ll report states"},{"line_number":230,"context_line":"    payload.update("},{"line_number":231,"context_line":"        _compute_states_payload("},{"line_number":232,"context_line":"            instance, old_vm_state, old_task_state,"},{"line_number":233,"context_line":"            new_vm_state, new_task_state))"},{"line_number":234,"context_line":""},{"line_number":235,"context_line":"    # add audit fields:"},{"line_number":236,"context_line":"    (audit_start, audit_end) \u003d audit_period_bounds(current_period\u003dTrue)"}],"source_content_type":"text/x-python","patch_set":17,"id":"ff0f0b1f_46704fdd","line":233,"range":{"start_line":229,"start_character":4,"end_line":233,"end_character":42},"in_reply_to":"ff0f0b1f_496e2dca","updated":"2017-05-26 00:29:32.000000000","message":"Yeah, I was planning to add a coment on this on the patchset but was disturbed by something","commit_id":"9d2ebbbc2d4dd542327d5d9ae0a32fdcb2ac976e"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"b66d7b92d0475dccc5d31b6773ad0bd762dd756e","unresolved":false,"context_lines":[{"line_number":226,"context_line":""},{"line_number":227,"context_line":"    payload \u003d info_from_instance(context, instance, None, None)"},{"line_number":228,"context_line":""},{"line_number":229,"context_line":"    # determine how we\u0027ll report states"},{"line_number":230,"context_line":"    payload.update("},{"line_number":231,"context_line":"        _compute_states_payload("},{"line_number":232,"context_line":"            instance, old_vm_state, old_task_state,"},{"line_number":233,"context_line":"            new_vm_state, new_task_state))"},{"line_number":234,"context_line":""},{"line_number":235,"context_line":"    # add audit fields:"},{"line_number":236,"context_line":"    (audit_start, audit_end) \u003d audit_period_bounds(current_period\u003dTrue)"}],"source_content_type":"text/x-python","patch_set":17,"id":"df140735_5ebfe5fa","line":233,"range":{"start_line":229,"start_character":4,"end_line":233,"end_character":42},"in_reply_to":"ff0f0b1f_71030c75","updated":"2017-05-30 01:30:46.000000000","message":"Ah yeah true, I was confused by the functional test having this:\n\n\u0027state_update.old_task_state\u0027: None,\n\u0027state_update.old_state\u0027: \u0027active\u0027,\n\nThe sample payload looks more realistic where the old/new task states are both null and the old/new states are both \u0027active\u0027, since nothing actually changed there.\n\nI didn\u0027t realize those were part of all instance update payloads.\n\nIt would be nice if the state_update field were nullable:\n\nhttp://git.openstack.org/cgit/openstack/nova/tree/nova/notifications/objects/instance.py#n176\n\nThen we could just null that part out to avoid any confusion. That might be worth getting gibi\u0027s opinion. Overall it\u0027s probably not a big deal though.","commit_id":"9d2ebbbc2d4dd542327d5d9ae0a32fdcb2ac976e"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"33c108a8fa693fc0d7487fd2f23471ab291a8e13","unresolved":false,"context_lines":[{"line_number":217,"context_line":"    return states_payload"},{"line_number":218,"context_line":""},{"line_number":219,"context_line":""},{"line_number":220,"context_line":"def send_instance_update_notification(context, instance, old_vm_state\u003dNone,"},{"line_number":221,"context_line":"            old_task_state\u003dNone, new_vm_state\u003dNone, new_task_state\u003dNone,"},{"line_number":222,"context_line":"            service\u003d\"compute\", host\u003dNone, old_display_name\u003dNone):"},{"line_number":223,"context_line":"    \"\"\"Send \u0027compute.instance.update\u0027 notification to inform observers"}],"source_content_type":"text/x-python","patch_set":21,"id":"df140735_f0150a3e","line":220,"updated":"2017-06-05 21:37:04.000000000","message":"Can we decorate this with @rpc.if_notifications_enabled like in this change?\n\nhttps://review.openstack.org/#/c/448779/23/nova/compute/utils.py@342\n\nThat way we don\u0027t go to the trouble of doing all this work if notifications are disabled.","commit_id":"4c868e265a2a826433bd603d28115e1eed4e9520"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"c801233d16f1b2760a06ceb07925350d9aa6b4c3","unresolved":false,"context_lines":[{"line_number":217,"context_line":"    return states_payload"},{"line_number":218,"context_line":""},{"line_number":219,"context_line":""},{"line_number":220,"context_line":"@rpc.if_notifications_enabled"},{"line_number":221,"context_line":"def send_instance_update_notification(context, instance, old_vm_state\u003dNone,"},{"line_number":222,"context_line":"            old_task_state\u003dNone, new_vm_state\u003dNone, new_task_state\u003dNone,"},{"line_number":223,"context_line":"            service\u003d\"compute\", host\u003dNone, old_display_name\u003dNone):"}],"source_content_type":"text/x-python","patch_set":23,"id":"df140735_137f4d66","line":220,"range":{"start_line":220,"start_character":5,"end_line":220,"end_character":29},"updated":"2017-06-06 15:35:35.000000000","message":"Can we add a simple test that makes sure that send_instance_update_notification is a noop if notifications are disabled?","commit_id":"ba75127c8c5084f8c13c5d4a01dd65d99c83f00f"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"2ea626751e2de06042bf54866dd6cb32d53a3436","unresolved":false,"context_lines":[{"line_number":217,"context_line":"    return states_payload"},{"line_number":218,"context_line":""},{"line_number":219,"context_line":""},{"line_number":220,"context_line":"@rpc.if_notifications_enabled"},{"line_number":221,"context_line":"def send_instance_update_notification(context, instance, old_vm_state\u003dNone,"},{"line_number":222,"context_line":"            old_task_state\u003dNone, new_vm_state\u003dNone, new_task_state\u003dNone,"},{"line_number":223,"context_line":"            service\u003d\"compute\", host\u003dNone, old_display_name\u003dNone):"}],"source_content_type":"text/x-python","patch_set":23,"id":"df140735_53d7054c","line":220,"range":{"start_line":220,"start_character":5,"end_line":220,"end_character":29},"in_reply_to":"df140735_137f4d66","updated":"2017-06-06 15:37:00.000000000","message":"We should probably also mention that we\u0027re adding this in the commit message since it seems semi-unrelated.","commit_id":"ba75127c8c5084f8c13c5d4a01dd65d99c83f00f"}],"nova/tests/functional/notification_sample_tests/test_instance.py":[{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"f3e01ccf0ccbea99f7c908429697afb39275ee84","unresolved":false,"context_lines":[{"line_number":166,"context_line":"        server \u003d self._boot_a_server("},{"line_number":167,"context_line":"            extra_params\u003d{\u0027networks\u0027: [{\u0027port\u0027: self.neutron.port_1[\u0027id\u0027]}]})"},{"line_number":168,"context_line":""},{"line_number":169,"context_line":"        instance_updates \u003d self._wait_for_notifications(\u0027instance.update\u0027, 8)"},{"line_number":170,"context_line":""},{"line_number":171,"context_line":"        # The first notification comes from the nova-conductor the"},{"line_number":172,"context_line":"        # rest is from the nova-compute. To keep the test simpler"}],"source_content_type":"text/x-python","patch_set":4,"id":"3f044301_22a37fb4","line":169,"updated":"2017-05-10 14:22:03.000000000","message":"As you expect to receive 8 update notification you should also assert the content of 8 update notifications at _verify_instance_update_steps() call.\n\nI think we expect that 8th notification comes because of https://github.com/openstack/nova/blob/master/nova/tests/functional/notification_sample_tests/notification_sample_base.py#L191 therefore the payload of the 8th notification should already contain the new \u0027tag1\u0027 added to the instance.","commit_id":"c44d0a8699b383c900c3429686f6668f69e76eca"},{"author":{"_account_id":15888,"name":"Zhenyu Zheng","email":"zheng.zhenyu@outlook.com","username":"Kevin_Zheng"},"change_message_id":"052c1148bdd6008c66116a72fe99408203e2bcc6","unresolved":false,"context_lines":[{"line_number":166,"context_line":"        server \u003d self._boot_a_server("},{"line_number":167,"context_line":"            extra_params\u003d{\u0027networks\u0027: [{\u0027port\u0027: self.neutron.port_1[\u0027id\u0027]}]})"},{"line_number":168,"context_line":""},{"line_number":169,"context_line":"        instance_updates \u003d self._wait_for_notifications(\u0027instance.update\u0027, 8)"},{"line_number":170,"context_line":""},{"line_number":171,"context_line":"        # The first notification comes from the nova-conductor the"},{"line_number":172,"context_line":"        # rest is from the nova-compute. To keep the test simpler"}],"source_content_type":"text/x-python","patch_set":4,"id":"3f044301_a5c30f38","line":169,"in_reply_to":"3f044301_22a37fb4","updated":"2017-05-11 01:27:31.000000000","message":"Done","commit_id":"c44d0a8699b383c900c3429686f6668f69e76eca"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"79fc883b7fddfc4a214ecec1406a72b60c4afd17","unresolved":false,"context_lines":[{"line_number":239,"context_line":"             \u0027power_state\u0027: \u0027running\u0027},"},{"line_number":240,"context_line":""},{"line_number":241,"context_line":"            # tag added"},{"line_number":242,"context_line":"            {\u0027state_update.old_task_state\u0027: None,"},{"line_number":243,"context_line":"             \u0027state_update.old_state\u0027: \u0027active\u0027,"},{"line_number":244,"context_line":"             \u0027tags\u0027: [\u0027tag1\u0027]},"},{"line_number":245,"context_line":"        ]"},{"line_number":246,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"ff0f0b1f_98e2bc9f","line":243,"range":{"start_line":242,"start_character":13,"end_line":243,"end_character":48},"updated":"2017-05-23 02:25:12.000000000","message":"This is what worried me about re-using that send_update method. Are these only in here because we didn\u0027t wait for the instance to be active before updating the tags?","commit_id":"c537ef443ae111f3a881b034e668ac9c49d49caa"},{"author":{"_account_id":15888,"name":"Zhenyu Zheng","email":"zheng.zhenyu@outlook.com","username":"Kevin_Zheng"},"change_message_id":"b15359f92928998c71b07329f993a09e662f1d1f","unresolved":false,"context_lines":[{"line_number":239,"context_line":"             \u0027power_state\u0027: \u0027running\u0027},"},{"line_number":240,"context_line":""},{"line_number":241,"context_line":"            # tag added"},{"line_number":242,"context_line":"            {\u0027state_update.old_task_state\u0027: None,"},{"line_number":243,"context_line":"             \u0027state_update.old_state\u0027: \u0027active\u0027,"},{"line_number":244,"context_line":"             \u0027tags\u0027: [\u0027tag1\u0027]},"},{"line_number":245,"context_line":"        ]"},{"line_number":246,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"ff0f0b1f_d3613507","line":243,"range":{"start_line":242,"start_character":13,"end_line":243,"end_character":48},"in_reply_to":"ff0f0b1f_98e2bc9f","updated":"2017-05-23 03:15:10.000000000","message":"No, the instance.vm_state was already ACTIVE before we add tags, as it is not supported to add tags while booting, this is here because the whole boot server method used for this test is:\nhttps://github.com/openstack/nova/blob/master/nova/tests/functional/notification_sample_tests/notification_sample_base.py#L191 it added tag to instance in  the last step.\nand previously adding tags does not sent out notify.","commit_id":"c537ef443ae111f3a881b034e668ac9c49d49caa"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"89e84874c43ed43bc173d33afc458d7415b02767","unresolved":false,"context_lines":[{"line_number":239,"context_line":"             \u0027power_state\u0027: \u0027running\u0027},"},{"line_number":240,"context_line":""},{"line_number":241,"context_line":"            # tag added"},{"line_number":242,"context_line":"            {\u0027state_update.old_task_state\u0027: None,"},{"line_number":243,"context_line":"             \u0027state_update.old_state\u0027: \u0027active\u0027,"},{"line_number":244,"context_line":"             \u0027tags\u0027: [\u0027tag1\u0027]},"},{"line_number":245,"context_line":"        ]"},{"line_number":246,"context_line":""}],"source_content_type":"text/x-python","patch_set":12,"id":"ff0f0b1f_eb051215","line":243,"range":{"start_line":242,"start_character":13,"end_line":243,"end_character":48},"updated":"2017-05-25 01:27:07.000000000","message":"It would be nice to leave a comment saying that the state_update changes are not really due to the tag being added, they are just picked up in that notification. Actually, why would the old_state be active here? Is this from when the instance is being deleted or something? This is confusing.","commit_id":"3522d24f813eecd77bd4255e477ea78294aa12c5"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"a78360093a0f1740018df7a1db4c31b843d05a7e","unresolved":false,"context_lines":[{"line_number":239,"context_line":"             \u0027power_state\u0027: \u0027running\u0027},"},{"line_number":240,"context_line":""},{"line_number":241,"context_line":"            # tag added"},{"line_number":242,"context_line":"            {\u0027state_update.old_task_state\u0027: None,"},{"line_number":243,"context_line":"             \u0027state_update.old_state\u0027: \u0027active\u0027,"},{"line_number":244,"context_line":"             \u0027tags\u0027: [\u0027tag1\u0027]},"},{"line_number":245,"context_line":"        ]"},{"line_number":246,"context_line":""}],"source_content_type":"text/x-python","patch_set":12,"id":"ff0f0b1f_2e6c38cc","line":243,"range":{"start_line":242,"start_character":13,"end_line":243,"end_character":48},"in_reply_to":"ff0f0b1f_eb051215","updated":"2017-05-25 01:34:00.000000000","message":"OK so I think the issue here is since you\u0027re sending the same instance for both old and new, the send_update method isn\u0027t expecting to be used this way. I think we need to build something into the send_update method that it doesn\u0027t include this information in the payload if nothing actually changed, but maybe control that behavior via a kwarg on the send_update method so we don\u0027t introduce some kind of backward incompatible change to how it works.","commit_id":"3522d24f813eecd77bd4255e477ea78294aa12c5"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"fc8629da26fb5638e9d9cb3ae52d9dc20eb5b12a","unresolved":false,"context_lines":[{"line_number":244,"context_line":"             \u0027power_state\u0027: \u0027running\u0027},"},{"line_number":245,"context_line":""},{"line_number":246,"context_line":"            # tag added"},{"line_number":247,"context_line":"            {\u0027state_update.old_task_state\u0027: None,"},{"line_number":248,"context_line":"             \u0027state_update.old_state\u0027: \u0027active\u0027,"},{"line_number":249,"context_line":"             \u0027tags\u0027: [\u0027tag1\u0027]},"},{"line_number":250,"context_line":"        ]"},{"line_number":251,"context_line":""}],"source_content_type":"text/x-python","patch_set":17,"id":"ff0f0b1f_ee08672e","line":248,"range":{"start_line":247,"start_character":13,"end_line":248,"end_character":48},"updated":"2017-05-25 17:25:22.000000000","message":"How did these get back in here?","commit_id":"9d2ebbbc2d4dd542327d5d9ae0a32fdcb2ac976e"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"33c108a8fa693fc0d7487fd2f23471ab291a8e13","unresolved":false,"context_lines":[{"line_number":173,"context_line":"        # eighth notification comes from nova-api the"},{"line_number":174,"context_line":"        # rest is from the nova-compute. To keep the test simpler"},{"line_number":175,"context_line":"        # assert this fact and then modify the publisher_id of the"},{"line_number":176,"context_line":"        # first notification to match the template"},{"line_number":177,"context_line":"        self.assertEqual(\u0027conductor:fake-mini\u0027,"},{"line_number":178,"context_line":"                         instance_updates[0][\u0027publisher_id\u0027])"},{"line_number":179,"context_line":"        self.assertEqual(\u0027nova-api:fake-mini\u0027,"}],"source_content_type":"text/x-python","patch_set":21,"id":"df140735_303942d6","line":176,"range":{"start_line":176,"start_character":10,"end_line":176,"end_character":15},"updated":"2017-06-05 21:37:04.000000000","message":"first and eighth","commit_id":"4c868e265a2a826433bd603d28115e1eed4e9520"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"33c108a8fa693fc0d7487fd2f23471ab291a8e13","unresolved":false,"context_lines":[{"line_number":179,"context_line":"        self.assertEqual(\u0027nova-api:fake-mini\u0027,"},{"line_number":180,"context_line":"                         instance_updates[7][\u0027publisher_id\u0027])"},{"line_number":181,"context_line":"        instance_updates[0][\u0027publisher_id\u0027] \u003d \u0027nova-compute:fake-mini\u0027"},{"line_number":182,"context_line":"        instance_updates[7][\u0027publisher_id\u0027] \u003d \u0027nova-compute:fake-mini\u0027"},{"line_number":183,"context_line":""},{"line_number":184,"context_line":"        create_steps \u003d ["},{"line_number":185,"context_line":"            # nothing -\u003e scheduling"}],"source_content_type":"text/x-python","patch_set":21,"id":"df140735_f02e2a8a","line":182,"range":{"start_line":182,"start_character":52,"end_line":182,"end_character":59},"updated":"2017-06-05 21:37:04.000000000","message":"This should be api right? I\u0027m not even sure why this is necessary because the sample is using the correct publisher:\n\nhttps://review.openstack.org/#/c/459923/21/doc/notification_samples/instance-update-tags-action.json@89\n\nAnd the test doesn\u0027t fail, so this seems unnecessary. The test probably doesn\u0027t fail here because it\u0027s not comparing to the same like test_create_delete_server does above.","commit_id":"4c868e265a2a826433bd603d28115e1eed4e9520"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"f9fa32e988337e248f17584e66fab7a172f00c66","unresolved":false,"context_lines":[{"line_number":179,"context_line":"        self.assertEqual(\u0027nova-api:fake-mini\u0027,"},{"line_number":180,"context_line":"                         instance_updates[7][\u0027publisher_id\u0027])"},{"line_number":181,"context_line":"        instance_updates[0][\u0027publisher_id\u0027] \u003d \u0027nova-compute:fake-mini\u0027"},{"line_number":182,"context_line":"        instance_updates[7][\u0027publisher_id\u0027] \u003d \u0027nova-compute:fake-mini\u0027"},{"line_number":183,"context_line":""},{"line_number":184,"context_line":"        create_steps \u003d ["},{"line_number":185,"context_line":"            # nothing -\u003e scheduling"}],"source_content_type":"text/x-python","patch_set":21,"id":"df140735_50971649","line":182,"range":{"start_line":182,"start_character":52,"end_line":182,"end_character":59},"in_reply_to":"df140735_f02e2a8a","updated":"2017-06-05 21:52:03.000000000","message":"Oh sorry I get it now - we assert it\u0027s API above, but have to hard-code to compute like we\u0027re doing for conductor, because that\u0027s what the tests use.","commit_id":"4c868e265a2a826433bd603d28115e1eed4e9520"}],"nova/tests/unit/api/openstack/compute/test_server_tags.py":[{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"79fc883b7fddfc4a214ecec1406a72b60c4afd17","unresolved":false,"context_lines":[{"line_number":92,"context_line":""},{"line_number":93,"context_line":"    @mock.patch(\u0027nova.db.instance_tag_set\u0027)"},{"line_number":94,"context_line":"    def test_update_all(self, mock_db_set_inst_tags):"},{"line_number":95,"context_line":"        self.stub_out(\u0027nova.api.openstack.common.get_instance\u0027, return_server)"},{"line_number":96,"context_line":"        fake_tags \u003d [self._get_tag(tag) for tag in TAGS]"},{"line_number":97,"context_line":"        mock_db_set_inst_tags.return_value \u003d fake_tags"},{"line_number":98,"context_line":"        req \u003d self._get_request("}],"source_content_type":"text/x-python","patch_set":7,"id":"ff0f0b1f_98fbdc45","side":"PARENT","line":95,"range":{"start_line":95,"start_character":8,"end_line":95,"end_character":78},"updated":"2017-05-23 02:25:12.000000000","message":"I\u0027m not really sure why this needed to change.","commit_id":"99bd33402ed70332fb8e141a0c6686674d58f051"},{"author":{"_account_id":15888,"name":"Zhenyu Zheng","email":"zheng.zhenyu@outlook.com","username":"Kevin_Zheng"},"change_message_id":"ca208d0d4fd8c420df8dd5257dc7dcfccc32ac5a","unresolved":false,"context_lines":[{"line_number":92,"context_line":""},{"line_number":93,"context_line":"    @mock.patch(\u0027nova.db.instance_tag_set\u0027)"},{"line_number":94,"context_line":"    def test_update_all(self, mock_db_set_inst_tags):"},{"line_number":95,"context_line":"        self.stub_out(\u0027nova.api.openstack.common.get_instance\u0027, return_server)"},{"line_number":96,"context_line":"        fake_tags \u003d [self._get_tag(tag) for tag in TAGS]"},{"line_number":97,"context_line":"        mock_db_set_inst_tags.return_value \u003d fake_tags"},{"line_number":98,"context_line":"        req \u003d self._get_request("}],"source_content_type":"text/x-python","patch_set":7,"id":"ff0f0b1f_ef3c4530","side":"PARENT","line":95,"range":{"start_line":95,"start_character":8,"end_line":95,"end_character":78},"in_reply_to":"ff0f0b1f_73294999","updated":"2017-05-23 08:29:21.000000000","message":"Ah, I do this change because I want to assert that the notify has been called with the server, and \"return_server\" is a method.","commit_id":"99bd33402ed70332fb8e141a0c6686674d58f051"},{"author":{"_account_id":15888,"name":"Zhenyu Zheng","email":"zheng.zhenyu@outlook.com","username":"Kevin_Zheng"},"change_message_id":"b15359f92928998c71b07329f993a09e662f1d1f","unresolved":false,"context_lines":[{"line_number":92,"context_line":""},{"line_number":93,"context_line":"    @mock.patch(\u0027nova.db.instance_tag_set\u0027)"},{"line_number":94,"context_line":"    def test_update_all(self, mock_db_set_inst_tags):"},{"line_number":95,"context_line":"        self.stub_out(\u0027nova.api.openstack.common.get_instance\u0027, return_server)"},{"line_number":96,"context_line":"        fake_tags \u003d [self._get_tag(tag) for tag in TAGS]"},{"line_number":97,"context_line":"        mock_db_set_inst_tags.return_value \u003d fake_tags"},{"line_number":98,"context_line":"        req \u003d self._get_request("}],"source_content_type":"text/x-python","patch_set":7,"id":"ff0f0b1f_73294999","side":"PARENT","line":95,"range":{"start_line":95,"start_character":8,"end_line":95,"end_character":78},"in_reply_to":"ff0f0b1f_98fbdc45","updated":"2017-05-23 03:15:10.000000000","message":"I will rework the API layer and also the tests.","commit_id":"99bd33402ed70332fb8e141a0c6686674d58f051"}],"releasenotes/notes/send-notification-when-instance-tag-changes-67c08000b6e0cd2a.yaml":[{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"fc8629da26fb5638e9d9cb3ae52d9dc20eb5b12a","unresolved":false,"context_lines":[{"line_number":1,"context_line":"---"},{"line_number":2,"context_line":"features:"},{"line_number":3,"context_line":"  - Versioned instance.update notification will be sent"},{"line_number":4,"context_line":"    when server\u0027s tags field got updated."}],"source_content_type":"text/x-yaml","patch_set":17,"id":"ff0f0b1f_c9611dd6","line":4,"range":{"start_line":4,"start_character":29,"end_line":4,"end_character":32},"updated":"2017-05-25 17:25:22.000000000","message":"is","commit_id":"9d2ebbbc2d4dd542327d5d9ae0a32fdcb2ac976e"},{"author":{"_account_id":15888,"name":"Zhenyu Zheng","email":"zheng.zhenyu@outlook.com","username":"Kevin_Zheng"},"change_message_id":"94ad0f326916d8d1540db15dd0e06ecda16250ef","unresolved":false,"context_lines":[{"line_number":1,"context_line":"---"},{"line_number":2,"context_line":"features:"},{"line_number":3,"context_line":"  - Versioned instance.update notification will be sent"},{"line_number":4,"context_line":"    when server\u0027s tags field got updated."}],"source_content_type":"text/x-yaml","patch_set":17,"id":"ff0f0b1f_864f8791","line":4,"range":{"start_line":4,"start_character":29,"end_line":4,"end_character":32},"in_reply_to":"ff0f0b1f_c9611dd6","updated":"2017-05-26 00:29:32.000000000","message":"Done","commit_id":"9d2ebbbc2d4dd542327d5d9ae0a32fdcb2ac976e"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"33c108a8fa693fc0d7487fd2f23471ab291a8e13","unresolved":false,"context_lines":[{"line_number":1,"context_line":"---"},{"line_number":2,"context_line":"features:"},{"line_number":3,"context_line":"  - Versioned instance.update notification will be sent"},{"line_number":4,"context_line":"    when server\u0027s tags field got updated."}],"source_content_type":"text/x-yaml","patch_set":21,"id":"df140735_10b75e3c","line":4,"range":{"start_line":4,"start_character":29,"end_line":4,"end_character":32},"updated":"2017-06-05 21:37:04.000000000","message":"is","commit_id":"4c868e265a2a826433bd603d28115e1eed4e9520"}]}
