)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"5994ccd28156e68ce047505d156b402b0301614d","unresolved":false,"context_lines":[{"line_number":4,"context_line":"Commit:     Nicolas Simonds \u003cnic@metacloud.com\u003e"},{"line_number":5,"context_line":"CommitDate: 2015-07-28 09:06:18 -0700"},{"line_number":6,"context_line":""},{"line_number":7,"context_line":"libvirt: Fix/implement revert-resize for RBD-backed images"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"* Makes a snapshot of Ceph-backed roots prior to resize"},{"line_number":10,"context_line":"* Rolls back to snapshot on revert"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":26,"id":"3a50d1a3_a4ccaa35","line":7,"updated":"2015-07-28 21:28:30.000000000","message":"If resize/revert doesn\u0027t work with ceph, why does the resiize/revert test in the ceph job pass?\n\nhttp://logs.openstack.org/57/187857/22/check/gate-tempest-dsvm-full-ceph/d197a34/console.html#_2015-07-28_21_07_13_174\n\n^ is from the dependent change.\n\nI\u0027m asking more from a POV of false positives in tests are not good, so we should understand that.","commit_id":"e8a7e4e4e4660924bc43d88833b1f7f476148412"},{"author":{"_account_id":5280,"name":"Nicolas Simonds","email":"nic@metacloud.com","username":"nicolas.simonds"},"change_message_id":"acee8cbbb4c9c491fb5ef4b4d3d7eccd4e56a5fe","unresolved":false,"context_lines":[{"line_number":4,"context_line":"Commit:     Nicolas Simonds \u003cnic@metacloud.com\u003e"},{"line_number":5,"context_line":"CommitDate: 2015-07-28 09:06:18 -0700"},{"line_number":6,"context_line":""},{"line_number":7,"context_line":"libvirt: Fix/implement revert-resize for RBD-backed images"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"* Makes a snapshot of Ceph-backed roots prior to resize"},{"line_number":10,"context_line":"* Rolls back to snapshot on revert"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":26,"id":"3a50d1a3_f9e01328","line":7,"in_reply_to":"3a50d1a3_a4ccaa35","updated":"2015-07-29 00:54:56.000000000","message":"Looking at the test, it looks like it checks the API results and looks at the flavor attributes, but never verifies the state of the backing store.\n\nIf it did, it would readily become apparent that without this patch, the resize is in fact skipped, and the flavor info on the instance is filled with lies.","commit_id":"e8a7e4e4e4660924bc43d88833b1f7f476148412"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"117dfa9ccc9198a80ecb267ebc96bfcaf40ca71f","unresolved":false,"context_lines":[{"line_number":10,"context_line":"* Rolls back to snapshot on revert"},{"line_number":11,"context_line":"* Destroys resize snapshots on image cleanup"},{"line_number":12,"context_line":""},{"line_number":13,"context_line":"Adds a CAN_SNAPSHOT attribute to libvirt image backends to say"},{"line_number":14,"context_line":"whether snapshot behavior is supported, so that other backends can"},{"line_number":15,"context_line":"implement their own workalike methods, if doing so makes sense."},{"line_number":16,"context_line":""}],"source_content_type":"text/x-gerrit-commit-message","patch_set":43,"id":"ba63e191_6f8962ca","line":13,"range":{"start_line":13,"start_character":7,"end_line":13,"end_character":19},"updated":"2016-01-18 19:58:04.000000000","message":"This is no longer the case.","commit_id":"17e2cecaaaafa6f3b6b141db7d0a02325b982947"},{"author":{"_account_id":5280,"name":"Nicolas Simonds","email":"nic@metacloud.com","username":"nicolas.simonds"},"change_message_id":"a14d0098a0a4546e17a7161e9bffbd3e96be31cb","unresolved":false,"context_lines":[{"line_number":10,"context_line":"* Rolls back to snapshot on revert"},{"line_number":11,"context_line":"* Destroys resize snapshots on image cleanup"},{"line_number":12,"context_line":""},{"line_number":13,"context_line":"Adds a CAN_SNAPSHOT attribute to libvirt image backends to say"},{"line_number":14,"context_line":"whether snapshot behavior is supported, so that other backends can"},{"line_number":15,"context_line":"implement their own workalike methods, if doing so makes sense."},{"line_number":16,"context_line":""}],"source_content_type":"text/x-gerrit-commit-message","patch_set":43,"id":"ba63e191_4f348fdd","line":13,"range":{"start_line":13,"start_character":7,"end_line":13,"end_character":19},"in_reply_to":"ba63e191_6f8962ca","updated":"2016-01-19 04:52:39.000000000","message":"Derp.","commit_id":"17e2cecaaaafa6f3b6b141db7d0a02325b982947"}],"nova/tests/unit/virt/libvirt/fake_imagebackend.py":[{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"117dfa9ccc9198a80ecb267ebc96bfcaf40ca71f","unresolved":false,"context_lines":[{"line_number":81,"context_line":"        pass"},{"line_number":82,"context_line":""},{"line_number":83,"context_line":""},{"line_number":84,"context_line":"class Snap(Raw):"},{"line_number":85,"context_line":"    # NOTE(nic): Added for instance resize tests that leverage filesystem"},{"line_number":86,"context_line":"    # snapshots"},{"line_number":87,"context_line":"    is_block_dev \u003d False"}],"source_content_type":"text/x-python","patch_set":43,"id":"ba63e191_af119a5f","line":84,"range":{"start_line":84,"start_character":0,"end_line":84,"end_character":16},"updated":"2016-01-18 19:58:04.000000000","message":"I\u0027m not sure that this is necessary as a stub object, mainly because in all of the tests that use this, you mock out the actual method calls on the object, so you could just use a Mock sentinel in those cases instead of defining this new stateless stub.","commit_id":"17e2cecaaaafa6f3b6b141db7d0a02325b982947"},{"author":{"_account_id":5280,"name":"Nicolas Simonds","email":"nic@metacloud.com","username":"nicolas.simonds"},"change_message_id":"a14d0098a0a4546e17a7161e9bffbd3e96be31cb","unresolved":false,"context_lines":[{"line_number":81,"context_line":"        pass"},{"line_number":82,"context_line":""},{"line_number":83,"context_line":""},{"line_number":84,"context_line":"class Snap(Raw):"},{"line_number":85,"context_line":"    # NOTE(nic): Added for instance resize tests that leverage filesystem"},{"line_number":86,"context_line":"    # snapshots"},{"line_number":87,"context_line":"    is_block_dev \u003d False"}],"source_content_type":"text/x-python","patch_set":43,"id":"ba63e191_975299dc","line":84,"range":{"start_line":84,"start_character":0,"end_line":84,"end_character":16},"in_reply_to":"ba63e191_af119a5f","updated":"2016-01-19 04:52:39.000000000","message":"Oh, that\u0027s much better.  Done.","commit_id":"17e2cecaaaafa6f3b6b141db7d0a02325b982947"}],"nova/tests/unit/virt/libvirt/fake_libvirt_utils.py":[{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"117dfa9ccc9198a80ecb267ebc96bfcaf40ca71f","unresolved":false,"context_lines":[{"line_number":23,"context_line":"disk_backing_files \u003d {}"},{"line_number":24,"context_line":"disk_type \u003d \"qcow2\""},{"line_number":25,"context_line":""},{"line_number":26,"context_line":"RESIZE_SNAPSHOT_NAME \u003d libvirt_utils.RESIZE_SNAPSHOT_NAME"},{"line_number":27,"context_line":""},{"line_number":28,"context_line":""},{"line_number":29,"context_line":"def create_image(disk_format, path, size):"}],"source_content_type":"text/x-python","patch_set":43,"id":"ba63e191_8ffff633","line":26,"updated":"2016-01-18 19:58:04.000000000","message":"Why is this needed?","commit_id":"17e2cecaaaafa6f3b6b141db7d0a02325b982947"},{"author":{"_account_id":5280,"name":"Nicolas Simonds","email":"nic@metacloud.com","username":"nicolas.simonds"},"change_message_id":"a14d0098a0a4546e17a7161e9bffbd3e96be31cb","unresolved":false,"context_lines":[{"line_number":23,"context_line":"disk_backing_files \u003d {}"},{"line_number":24,"context_line":"disk_type \u003d \"qcow2\""},{"line_number":25,"context_line":""},{"line_number":26,"context_line":"RESIZE_SNAPSHOT_NAME \u003d libvirt_utils.RESIZE_SNAPSHOT_NAME"},{"line_number":27,"context_line":""},{"line_number":28,"context_line":""},{"line_number":29,"context_line":"def create_image(disk_format, path, size):"}],"source_content_type":"text/x-python","patch_set":43,"id":"ba63e191_0fe9b71a","line":26,"in_reply_to":"ba63e191_8ffff633","updated":"2016-01-19 04:52:39.000000000","message":"Because trying to import symbols from libvirt_utils directly when fake_libvirt_utils is in use causes it to barf everywhere.  This module is littered with \"return this value from libvirt_utils\" helpers, I\u0027m guessing because of that very phenomena.","commit_id":"17e2cecaaaafa6f3b6b141db7d0a02325b982947"}],"nova/tests/unit/virt/libvirt/test_driver.py":[{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"117dfa9ccc9198a80ecb267ebc96bfcaf40ca71f","unresolved":false,"context_lines":[{"line_number":8839,"context_line":"    @mock.patch.object(nova.virt.libvirt.imagebackend.Image, \u0027cache\u0027)"},{"line_number":8840,"context_line":"    def test_create_image_resize_snap_backend(self, mock_cache):"},{"line_number":8841,"context_line":"        drvr \u003d libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)"},{"line_number":8842,"context_line":"        drvr.image_backend \u003d fake_imagebackend.Snap()"},{"line_number":8843,"context_line":"        instance \u003d objects.Instance(**self.test_instance)"},{"line_number":8844,"context_line":"        instance.task_state \u003d task_states.RESIZE_FINISH"},{"line_number":8845,"context_line":"        image_meta \u003d objects.ImageMeta.from_dict(self.test_image_meta)"}],"source_content_type":"text/x-python","patch_set":43,"id":"ba63e191_5248c15b","line":8842,"range":{"start_line":8842,"start_character":8,"end_line":8842,"end_character":53},"updated":"2016-01-18 19:58:04.000000000","message":"Couldn\u0027t we just as easily do something like:\n\ndrvr.image_backend \u003d mock.Mock()\n\n?\n\nI\u0027m not sure that the fake_imagebackend.Snap() object is useful in any of these tests since the methods on it are all mocked out anyway.","commit_id":"17e2cecaaaafa6f3b6b141db7d0a02325b982947"},{"author":{"_account_id":5280,"name":"Nicolas Simonds","email":"nic@metacloud.com","username":"nicolas.simonds"},"change_message_id":"a14d0098a0a4546e17a7161e9bffbd3e96be31cb","unresolved":false,"context_lines":[{"line_number":8839,"context_line":"    @mock.patch.object(nova.virt.libvirt.imagebackend.Image, \u0027cache\u0027)"},{"line_number":8840,"context_line":"    def test_create_image_resize_snap_backend(self, mock_cache):"},{"line_number":8841,"context_line":"        drvr \u003d libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)"},{"line_number":8842,"context_line":"        drvr.image_backend \u003d fake_imagebackend.Snap()"},{"line_number":8843,"context_line":"        instance \u003d objects.Instance(**self.test_instance)"},{"line_number":8844,"context_line":"        instance.task_state \u003d task_states.RESIZE_FINISH"},{"line_number":8845,"context_line":"        image_meta \u003d objects.ImageMeta.from_dict(self.test_image_meta)"}],"source_content_type":"text/x-python","patch_set":43,"id":"ba63e191_372c0d4a","line":8842,"range":{"start_line":8842,"start_character":8,"end_line":8842,"end_character":53},"in_reply_to":"ba63e191_5248c15b","updated":"2016-01-19 04:52:39.000000000","message":"Done","commit_id":"17e2cecaaaafa6f3b6b141db7d0a02325b982947"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"117dfa9ccc9198a80ecb267ebc96bfcaf40ca71f","unresolved":false,"context_lines":[{"line_number":13699,"context_line":"                mock.patch.object(utils, \u0027get_image_from_system_metadata\u0027),"},{"line_number":13700,"context_line":"                mock.patch.object(drvr, \u0027_create_domain_and_network\u0027),"},{"line_number":13701,"context_line":"                mock.patch.object(drvr, \u0027_get_guest_xml\u0027),"},{"line_number":13702,"context_line":"                mock.patch.object(drvr.image_backend, \u0027rollback_to_snap\u0027),"},{"line_number":13703,"context_line":"                mock.patch.object(drvr.image_backend, \u0027remove_snap\u0027)) as ("},{"line_number":13704,"context_line":"                mock_image, mock_cdn, mock_ggx, mock_rollback, mock_remove):"},{"line_number":13705,"context_line":"            mock_image.return_value \u003d {\u0027disk_format\u0027: \u0027raw\u0027}"}],"source_content_type":"text/x-python","patch_set":43,"id":"ba63e191_d2ecb191","line":13702,"range":{"start_line":13702,"start_character":55,"end_line":13702,"end_character":71},"updated":"2016-01-18 19:58:04.000000000","message":"We should also test the case where this raises SnapshotNotFound.","commit_id":"17e2cecaaaafa6f3b6b141db7d0a02325b982947"},{"author":{"_account_id":5280,"name":"Nicolas Simonds","email":"nic@metacloud.com","username":"nicolas.simonds"},"change_message_id":"a14d0098a0a4546e17a7161e9bffbd3e96be31cb","unresolved":false,"context_lines":[{"line_number":13699,"context_line":"                mock.patch.object(utils, \u0027get_image_from_system_metadata\u0027),"},{"line_number":13700,"context_line":"                mock.patch.object(drvr, \u0027_create_domain_and_network\u0027),"},{"line_number":13701,"context_line":"                mock.patch.object(drvr, \u0027_get_guest_xml\u0027),"},{"line_number":13702,"context_line":"                mock.patch.object(drvr.image_backend, \u0027rollback_to_snap\u0027),"},{"line_number":13703,"context_line":"                mock.patch.object(drvr.image_backend, \u0027remove_snap\u0027)) as ("},{"line_number":13704,"context_line":"                mock_image, mock_cdn, mock_ggx, mock_rollback, mock_remove):"},{"line_number":13705,"context_line":"            mock_image.return_value \u003d {\u0027disk_format\u0027: \u0027raw\u0027}"}],"source_content_type":"text/x-python","patch_set":43,"id":"ba63e191_daa03893","line":13702,"range":{"start_line":13702,"start_character":55,"end_line":13702,"end_character":71},"in_reply_to":"ba63e191_d2ecb191","updated":"2016-01-19 04:52:39.000000000","message":"Done","commit_id":"17e2cecaaaafa6f3b6b141db7d0a02325b982947"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"c984711215130edf5376b460ba29b3081b4ac9c9","unresolved":false,"context_lines":[{"line_number":13741,"context_line":"                                  side_effect\u003dfake_get_guest_xml)):"},{"line_number":13742,"context_line":"            drvr.finish_revert_migration(\u0027\u0027, instance, None, power_on\u003dFalse)"},{"line_number":13743,"context_line":""},{"line_number":13744,"context_line":"    def test_finish_revert_migration_snap_backend(self):"},{"line_number":13745,"context_line":"        drvr \u003d libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)"},{"line_number":13746,"context_line":"        drvr.image_backend \u003d mock.Mock()"},{"line_number":13747,"context_line":"        drvr.image_backend.image.return_value \u003d drvr.image_backend"}],"source_content_type":"text/x-python","patch_set":44,"id":"9a68dd71_3612cfb5","line":13744,"range":{"start_line":13744,"start_character":8,"end_line":13744,"end_character":49},"updated":"2016-01-20 19:29:20.000000000","message":"Shouldn\u0027t you be asserting that rollback_to_snap and remove_snap is called in here somewhere?","commit_id":"d04d1164cc7d2405055fdeee41a9e5a4d06b6d0f"},{"author":{"_account_id":5280,"name":"Nicolas Simonds","email":"nic@metacloud.com","username":"nicolas.simonds"},"change_message_id":"a8160063f699147ee9bceaa4b040a1ac4b0e91fb","unresolved":false,"context_lines":[{"line_number":13741,"context_line":"                                  side_effect\u003dfake_get_guest_xml)):"},{"line_number":13742,"context_line":"            drvr.finish_revert_migration(\u0027\u0027, instance, None, power_on\u003dFalse)"},{"line_number":13743,"context_line":""},{"line_number":13744,"context_line":"    def test_finish_revert_migration_snap_backend(self):"},{"line_number":13745,"context_line":"        drvr \u003d libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)"},{"line_number":13746,"context_line":"        drvr.image_backend \u003d mock.Mock()"},{"line_number":13747,"context_line":"        drvr.image_backend.image.return_value \u003d drvr.image_backend"}],"source_content_type":"text/x-python","patch_set":44,"id":"9a68dd71_d6ad7332","line":13744,"range":{"start_line":13744,"start_character":8,"end_line":13744,"end_character":49},"in_reply_to":"9a68dd71_3612cfb5","updated":"2016-01-20 19:32:10.000000000","message":"Done  ;-)","commit_id":"d04d1164cc7d2405055fdeee41a9e5a4d06b6d0f"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"6a1b0b859cae1bbceff95bea899a2bda05c2db9f","unresolved":false,"context_lines":[{"line_number":13755,"context_line":"            mock_image.return_value \u003d {\u0027disk_format\u0027: \u0027raw\u0027}"},{"line_number":13756,"context_line":"            drvr.finish_revert_migration(\u0027\u0027, ins_ref, None, power_on\u003dFalse)"},{"line_number":13757,"context_line":""},{"line_number":13758,"context_line":"            drvr.image_backend.rollback_to_snap.assert_called_once_with("},{"line_number":13759,"context_line":"                    libvirt_utils.RESIZE_SNAPSHOT_NAME)"},{"line_number":13760,"context_line":"            drvr.image_backend.remove_snap.assert_called_once_with("},{"line_number":13761,"context_line":"                    libvirt_utils.RESIZE_SNAPSHOT_NAME, ignore_errors\u003dTrue)"},{"line_number":13762,"context_line":""},{"line_number":13763,"context_line":"    def test_finish_revert_migration_snap_backend_snapshot_not_found(self):"},{"line_number":13764,"context_line":"        drvr \u003d libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)"}],"source_content_type":"text/x-python","patch_set":44,"id":"9a68dd71_7681278f","line":13761,"range":{"start_line":13758,"start_character":12,"end_line":13761,"end_character":75},"updated":"2016-01-20 19:32:12.000000000","message":"OK, I see, used here.","commit_id":"d04d1164cc7d2405055fdeee41a9e5a4d06b6d0f"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"c984711215130edf5376b460ba29b3081b4ac9c9","unresolved":false,"context_lines":[{"line_number":13777,"context_line":"                    snapshot_id\u003d\u0027testing\u0027)"},{"line_number":13778,"context_line":"            drvr.finish_revert_migration(\u0027\u0027, ins_ref, None, power_on\u003dFalse)"},{"line_number":13779,"context_line":""},{"line_number":13780,"context_line":"            self.assertRaises(exception.SnapshotNotFound,"},{"line_number":13781,"context_line":"                              mock_rbd.rollback_to_snap,"},{"line_number":13782,"context_line":"                              libvirt_utils.RESIZE_SNAPSHOT_NAME)"},{"line_number":13783,"context_line":"            drvr.image_backend.remove_snap.assert_called_once_with("},{"line_number":13784,"context_line":"                    libvirt_utils.RESIZE_SNAPSHOT_NAME, ignore_errors\u003dTrue)"},{"line_number":13785,"context_line":""}],"source_content_type":"text/x-python","patch_set":44,"id":"9a68dd71_16030b75","line":13782,"range":{"start_line":13780,"start_character":12,"end_line":13782,"end_character":65},"updated":"2016-01-20 19:29:20.000000000","message":"This is silly, you\u0027re asserting that the mock is raising the exception that you told it to raise from the side_effect.\n\nI think you just want:\n\nmock_rbd.rollback_to_snap.assert_called_once_with(libvirt_utils.RESIZE_SNAPSHOT_NAME)\n\nSeems like you should also be asserting that we still call remove_snap in here even though rollback_to_snap raised the error.","commit_id":"d04d1164cc7d2405055fdeee41a9e5a4d06b6d0f"},{"author":{"_account_id":5280,"name":"Nicolas Simonds","email":"nic@metacloud.com","username":"nicolas.simonds"},"change_message_id":"a8160063f699147ee9bceaa4b040a1ac4b0e91fb","unresolved":false,"context_lines":[{"line_number":13777,"context_line":"                    snapshot_id\u003d\u0027testing\u0027)"},{"line_number":13778,"context_line":"            drvr.finish_revert_migration(\u0027\u0027, ins_ref, None, power_on\u003dFalse)"},{"line_number":13779,"context_line":""},{"line_number":13780,"context_line":"            self.assertRaises(exception.SnapshotNotFound,"},{"line_number":13781,"context_line":"                              mock_rbd.rollback_to_snap,"},{"line_number":13782,"context_line":"                              libvirt_utils.RESIZE_SNAPSHOT_NAME)"},{"line_number":13783,"context_line":"            drvr.image_backend.remove_snap.assert_called_once_with("},{"line_number":13784,"context_line":"                    libvirt_utils.RESIZE_SNAPSHOT_NAME, ignore_errors\u003dTrue)"},{"line_number":13785,"context_line":""}],"source_content_type":"text/x-python","patch_set":44,"id":"9a68dd71_3663af1c","line":13782,"range":{"start_line":13780,"start_character":12,"end_line":13782,"end_character":65},"in_reply_to":"9a68dd71_16030b75","updated":"2016-01-20 19:32:10.000000000","message":"Done","commit_id":"d04d1164cc7d2405055fdeee41a9e5a4d06b6d0f"}],"nova/utils.py":[{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"78946a88831a7b8dc880bb0ea58817d9e391fa36","unresolved":false,"context_lines":[{"line_number":194,"context_line":""},{"line_number":195,"context_line":"_FILE_CACHE \u003d {}"},{"line_number":196,"context_line":""},{"line_number":197,"context_line":"RESIZE_SNAPSHOT_NAME \u003d \u0027nova-resize\u0027"},{"line_number":198,"context_line":""},{"line_number":199,"context_line":""},{"line_number":200,"context_line":"def vpn_ping(address, port, timeout\u003d0.05, session_id\u003dNone):"}],"source_content_type":"text/x-python","patch_set":42,"id":"da6ed579_d43d6fbc","line":197,"updated":"2016-01-16 18:48:46.000000000","message":"I don\u0027t think this really belongs here. The constant is only used in the libvirt sub-module, so I\u0027d put it somewhere in there, either in the driver code or the libvirt imagebackend module - the latter probably makes the most sense.","commit_id":"b0ad491ec1abae2c5cbbe6e6d98d90b4abbb9b3f"},{"author":{"_account_id":5280,"name":"Nicolas Simonds","email":"nic@metacloud.com","username":"nicolas.simonds"},"change_message_id":"f46920799f375a23b4e37e0adbb54e1f14f7b320","unresolved":false,"context_lines":[{"line_number":194,"context_line":""},{"line_number":195,"context_line":"_FILE_CACHE \u003d {}"},{"line_number":196,"context_line":""},{"line_number":197,"context_line":"RESIZE_SNAPSHOT_NAME \u003d \u0027nova-resize\u0027"},{"line_number":198,"context_line":""},{"line_number":199,"context_line":""},{"line_number":200,"context_line":"def vpn_ping(address, port, timeout\u003d0.05, session_id\u003dNone):"}],"source_content_type":"text/x-python","patch_set":42,"id":"da6ed579_42a9afde","line":197,"in_reply_to":"da6ed579_d43d6fbc","updated":"2016-01-18 07:06:44.000000000","message":"Done","commit_id":"b0ad491ec1abae2c5cbbe6e6d98d90b4abbb9b3f"}],"nova/virt/libvirt/driver.py":[{"author":{"_account_id":7135,"name":"Liang Chen","email":"liangchen.linux@gmail.com","username":"Liang"},"change_message_id":"081ff4bf4684add4b6397c27c533dc186ae03a95","unresolved":false,"context_lines":[{"line_number":6408,"context_line":"            size \u003d self._disk_size_from_instance(instance, info)"},{"line_number":6409,"context_line":"            if resize_instance:"},{"line_number":6410,"context_line":"                image \u003d imgmodel.LocalFileImage(info[\u0027path\u0027],"},{"line_number":6411,"context_line":"                                                info[\u0027type\u0027])"},{"line_number":6412,"context_line":"                self._disk_resize(image, size)"},{"line_number":6413,"context_line":"            if info[\u0027type\u0027] \u003d\u003d \u0027raw\u0027 and CONF.use_cow_images:"},{"line_number":6414,"context_line":"                self._disk_raw_to_qcow2(info[\u0027path\u0027])"}],"source_content_type":"text/x-python","patch_set":26,"id":"3a50d1a3_f802e308","line":6411,"updated":"2015-07-30 20:26:36.000000000","message":"It seems to me that this is where the disk(qcow/raw) resize currently takes place at. Any particular reason for moving rbd backed disk resize to _create_image?","commit_id":"e8a7e4e4e4660924bc43d88833b1f7f476148412"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"1db548eb63a9722d0ca3bfc1e3d40326b2708e0d","unresolved":false,"context_lines":[{"line_number":1076,"context_line":"                          attempts\u003d5)"},{"line_number":1077,"context_line":""},{"line_number":1078,"context_line":"        backend \u003d self.image_backend.image(instance, \u0027disk\u0027,"},{"line_number":1079,"context_line":"                                           CONF.libvirt.images_type)"},{"line_number":1080,"context_line":"        if backend.CAN_SNAPSHOT:"},{"line_number":1081,"context_line":"            backend.remove_snap(\u0027nova-resize\u0027)"},{"line_number":1082,"context_line":""}],"source_content_type":"text/x-python","patch_set":39,"id":"da6ed579_2cedbbef","line":1079,"range":{"start_line":1079,"start_character":43,"end_line":1079,"end_character":67},"updated":"2016-01-15 20:05:02.000000000","message":"nit: you can omit this, it\u0027s the default in the image backend code.","commit_id":"459f564ea6aa603f7667e150f302efc9f51c6441"},{"author":{"_account_id":5280,"name":"Nicolas Simonds","email":"nic@metacloud.com","username":"nicolas.simonds"},"change_message_id":"f6cf8ea8b36518e5817502218a18d9b4fbb3f3ce","unresolved":false,"context_lines":[{"line_number":1076,"context_line":"                          attempts\u003d5)"},{"line_number":1077,"context_line":""},{"line_number":1078,"context_line":"        backend \u003d self.image_backend.image(instance, \u0027disk\u0027,"},{"line_number":1079,"context_line":"                                           CONF.libvirt.images_type)"},{"line_number":1080,"context_line":"        if backend.CAN_SNAPSHOT:"},{"line_number":1081,"context_line":"            backend.remove_snap(\u0027nova-resize\u0027)"},{"line_number":1082,"context_line":""}],"source_content_type":"text/x-python","patch_set":39,"id":"da6ed579_dd97dd38","line":1079,"range":{"start_line":1079,"start_character":43,"end_line":1079,"end_character":67},"in_reply_to":"da6ed579_2cedbbef","updated":"2016-01-16 07:14:59.000000000","message":"Done","commit_id":"459f564ea6aa603f7667e150f302efc9f51c6441"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"1db548eb63a9722d0ca3bfc1e3d40326b2708e0d","unresolved":false,"context_lines":[{"line_number":1078,"context_line":"        backend \u003d self.image_backend.image(instance, \u0027disk\u0027,"},{"line_number":1079,"context_line":"                                           CONF.libvirt.images_type)"},{"line_number":1080,"context_line":"        if backend.CAN_SNAPSHOT:"},{"line_number":1081,"context_line":"            backend.remove_snap(\u0027nova-resize\u0027)"},{"line_number":1082,"context_line":""},{"line_number":1083,"context_line":"        if instance.host !\u003d CONF.host:"},{"line_number":1084,"context_line":"            self._undefine_domain(instance)"}],"source_content_type":"text/x-python","patch_set":39,"id":"da6ed579_4ca26f9c","line":1081,"range":{"start_line":1081,"start_character":32,"end_line":1081,"end_character":45},"updated":"2016-01-15 20:05:02.000000000","message":"Do we want to make this a global constant?","commit_id":"459f564ea6aa603f7667e150f302efc9f51c6441"},{"author":{"_account_id":5280,"name":"Nicolas Simonds","email":"nic@metacloud.com","username":"nicolas.simonds"},"change_message_id":"f6cf8ea8b36518e5817502218a18d9b4fbb3f3ce","unresolved":false,"context_lines":[{"line_number":1078,"context_line":"        backend \u003d self.image_backend.image(instance, \u0027disk\u0027,"},{"line_number":1079,"context_line":"                                           CONF.libvirt.images_type)"},{"line_number":1080,"context_line":"        if backend.CAN_SNAPSHOT:"},{"line_number":1081,"context_line":"            backend.remove_snap(\u0027nova-resize\u0027)"},{"line_number":1082,"context_line":""},{"line_number":1083,"context_line":"        if instance.host !\u003d CONF.host:"},{"line_number":1084,"context_line":"            self._undefine_domain(instance)"}],"source_content_type":"text/x-python","patch_set":39,"id":"da6ed579_9da2c599","line":1081,"range":{"start_line":1081,"start_character":32,"end_line":1081,"end_character":45},"in_reply_to":"da6ed579_4ca26f9c","updated":"2016-01-16 07:14:59.000000000","message":"Done","commit_id":"459f564ea6aa603f7667e150f302efc9f51c6441"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"1db548eb63a9722d0ca3bfc1e3d40326b2708e0d","unresolved":false,"context_lines":[{"line_number":2948,"context_line":""},{"line_number":2949,"context_line":"            backend \u003d image(\u0027disk\u0027)"},{"line_number":2950,"context_line":"            if (backend.CAN_SNAPSHOT and"},{"line_number":2951,"context_line":"                        instance.task_state \u003d\u003d task_states.RESIZE_FINISH):"},{"line_number":2952,"context_line":"                backend.create_snap(\u0027nova-resize\u0027)"},{"line_number":2953,"context_line":"            if backend.SUPPORTS_CLONE:"},{"line_number":2954,"context_line":"                def clone_fallback_to_fetch(*args, **kwargs):"}],"source_content_type":"text/x-python","patch_set":39,"id":"da6ed579_6c3bb339","line":2951,"range":{"start_line":2951,"start_character":24,"end_line":2951,"end_character":72},"updated":"2016-01-15 20:05:02.000000000","message":"This is a bit gross, since it\u0027s tying this to the state model in the compute manager. It\u0027s not the end of the world, but an alternative would be to just check if fallback_from_host is not None since that\u0027s the case when finishing a resize/migration. Maybe danpb has an opinion on what he\u0027d like better.","commit_id":"459f564ea6aa603f7667e150f302efc9f51c6441"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"0fa5dc935f7e9a16e3fa1a45e6e937fd4192bb04","unresolved":false,"context_lines":[{"line_number":2948,"context_line":""},{"line_number":2949,"context_line":"            backend \u003d image(\u0027disk\u0027)"},{"line_number":2950,"context_line":"            if (backend.CAN_SNAPSHOT and"},{"line_number":2951,"context_line":"                        instance.task_state \u003d\u003d task_states.RESIZE_FINISH):"},{"line_number":2952,"context_line":"                backend.create_snap(\u0027nova-resize\u0027)"},{"line_number":2953,"context_line":"            if backend.SUPPORTS_CLONE:"},{"line_number":2954,"context_line":"                def clone_fallback_to_fetch(*args, **kwargs):"}],"source_content_type":"text/x-python","patch_set":39,"id":"da6ed579_af019d6c","line":2951,"range":{"start_line":2951,"start_character":24,"end_line":2951,"end_character":72},"in_reply_to":"da6ed579_6c3bb339","updated":"2016-01-15 20:21:04.000000000","message":"BTW, I checked and other virt drivers have similar types of checks on the instance.task_state, and one could argue this is more explicit, so I\u0027m fine with leaving that in.","commit_id":"459f564ea6aa603f7667e150f302efc9f51c6441"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"1db548eb63a9722d0ca3bfc1e3d40326b2708e0d","unresolved":false,"context_lines":[{"line_number":7051,"context_line":"        image_meta \u003d objects.ImageMeta.from_instance(instance)"},{"line_number":7052,"context_line":""},{"line_number":7053,"context_line":"        backend \u003d self.image_backend.image(instance, \u0027disk\u0027,"},{"line_number":7054,"context_line":"                                           CONF.libvirt.images_type)"},{"line_number":7055,"context_line":"        # Once we rollback, the snapshot is no longer needed, so remove it"},{"line_number":7056,"context_line":"        if backend.CAN_SNAPSHOT:"},{"line_number":7057,"context_line":"            backend.rollback_to_snap(\u0027nova-resize\u0027)"}],"source_content_type":"text/x-python","patch_set":39,"id":"da6ed579_ccd17f31","line":7054,"range":{"start_line":7054,"start_character":43,"end_line":7054,"end_character":66},"updated":"2016-01-15 20:05:02.000000000","message":"nit: the code defaults to using this so you could omit it.","commit_id":"459f564ea6aa603f7667e150f302efc9f51c6441"},{"author":{"_account_id":5280,"name":"Nicolas Simonds","email":"nic@metacloud.com","username":"nicolas.simonds"},"change_message_id":"f6cf8ea8b36518e5817502218a18d9b4fbb3f3ce","unresolved":false,"context_lines":[{"line_number":7051,"context_line":"        image_meta \u003d objects.ImageMeta.from_instance(instance)"},{"line_number":7052,"context_line":""},{"line_number":7053,"context_line":"        backend \u003d self.image_backend.image(instance, \u0027disk\u0027,"},{"line_number":7054,"context_line":"                                           CONF.libvirt.images_type)"},{"line_number":7055,"context_line":"        # Once we rollback, the snapshot is no longer needed, so remove it"},{"line_number":7056,"context_line":"        if backend.CAN_SNAPSHOT:"},{"line_number":7057,"context_line":"            backend.rollback_to_snap(\u0027nova-resize\u0027)"}],"source_content_type":"text/x-python","patch_set":39,"id":"da6ed579_bd9f894f","line":7054,"range":{"start_line":7054,"start_character":43,"end_line":7054,"end_character":66},"in_reply_to":"da6ed579_ccd17f31","updated":"2016-01-16 07:14:59.000000000","message":"Done","commit_id":"459f564ea6aa603f7667e150f302efc9f51c6441"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"1db548eb63a9722d0ca3bfc1e3d40326b2708e0d","unresolved":false,"context_lines":[{"line_number":7054,"context_line":"                                           CONF.libvirt.images_type)"},{"line_number":7055,"context_line":"        # Once we rollback, the snapshot is no longer needed, so remove it"},{"line_number":7056,"context_line":"        if backend.CAN_SNAPSHOT:"},{"line_number":7057,"context_line":"            backend.rollback_to_snap(\u0027nova-resize\u0027)"},{"line_number":7058,"context_line":"            backend.remove_snap(\u0027nova-resize\u0027)"},{"line_number":7059,"context_line":""},{"line_number":7060,"context_line":"        disk_info \u003d blockinfo.get_disk_info(CONF.libvirt.virt_type,"}],"source_content_type":"text/x-python","patch_set":39,"id":"da6ed579_2cf85b49","line":7057,"range":{"start_line":7057,"start_character":12,"end_line":7057,"end_character":51},"updated":"2016-01-15 20:05:02.000000000","message":"This will raise a MigrationError if the nova-resize snapshot is not found, is there any way we could get into an upgrade issue here where we\u0027ve resized (old code) and while the resize is pending, the compute is upgraded and then the resize is reverted, thus hitting this new code which is going to fail to find the nova-resize snap and blow up.\n\nAm I being too cautious? Or should we play it safe and handle MigrationError for one release and remove in N?","commit_id":"459f564ea6aa603f7667e150f302efc9f51c6441"},{"author":{"_account_id":5280,"name":"Nicolas Simonds","email":"nic@metacloud.com","username":"nicolas.simonds"},"change_message_id":"f6cf8ea8b36518e5817502218a18d9b4fbb3f3ce","unresolved":false,"context_lines":[{"line_number":7054,"context_line":"                                           CONF.libvirt.images_type)"},{"line_number":7055,"context_line":"        # Once we rollback, the snapshot is no longer needed, so remove it"},{"line_number":7056,"context_line":"        if backend.CAN_SNAPSHOT:"},{"line_number":7057,"context_line":"            backend.rollback_to_snap(\u0027nova-resize\u0027)"},{"line_number":7058,"context_line":"            backend.remove_snap(\u0027nova-resize\u0027)"},{"line_number":7059,"context_line":""},{"line_number":7060,"context_line":"        disk_info \u003d blockinfo.get_disk_info(CONF.libvirt.virt_type,"}],"source_content_type":"text/x-python","patch_set":39,"id":"da6ed579_dd811dc5","line":7057,"range":{"start_line":7057,"start_character":12,"end_line":7057,"end_character":51},"in_reply_to":"da6ed579_2cf85b49","updated":"2016-01-16 07:14:59.000000000","message":"I come from the school of thought that says \"never catch an exception you don\u0027t know how to handle\"\n\nNow, I might be suffering from an abject lack of imagination here, but I can\u0027t think of any sane way to differentiate between instances unable to rollback to a snapshot due to upgraded software, and instances unable to rollback due to the snapshot being otherwise broken.\n\nSince the bug that this patch is fixing involves n-cpu neglecting to alter the disk geometry at all (and then lying about having done it) I don\u0027t know which is the worse outcome.  Maybe just stick it the errata for the release?","commit_id":"459f564ea6aa603f7667e150f302efc9f51c6441"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"a7158044f714966fbcfcc6adc3a7bbf43823a762","unresolved":false,"context_lines":[{"line_number":7054,"context_line":"                                           CONF.libvirt.images_type)"},{"line_number":7055,"context_line":"        # Once we rollback, the snapshot is no longer needed, so remove it"},{"line_number":7056,"context_line":"        if backend.CAN_SNAPSHOT:"},{"line_number":7057,"context_line":"            backend.rollback_to_snap(\u0027nova-resize\u0027)"},{"line_number":7058,"context_line":"            backend.remove_snap(\u0027nova-resize\u0027)"},{"line_number":7059,"context_line":""},{"line_number":7060,"context_line":"        disk_info \u003d blockinfo.get_disk_info(CONF.libvirt.virt_type,"}],"source_content_type":"text/x-python","patch_set":39,"id":"da6ed579_a068b988","line":7057,"range":{"start_line":7057,"start_character":12,"end_line":7057,"end_character":51},"in_reply_to":"da6ed579_dd811dc5","updated":"2016-01-16 14:41:20.000000000","message":"I\u0027d be OK if you want to put a release note in this change that says there is a chance that on upgrades if there were rbd-backed instances that are in a pending resize status, that on revert they could fail. I\u0027m not sure what the cleanup is in that case though, manual cleanup sucks. This is why I was saying we could have a try/except handler in here for 1 release and then remove it in newton.","commit_id":"459f564ea6aa603f7667e150f302efc9f51c6441"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"78946a88831a7b8dc880bb0ea58817d9e391fa36","unresolved":false,"context_lines":[{"line_number":7052,"context_line":"        backend \u003d self.image_backend.image(instance, \u0027disk\u0027)"},{"line_number":7053,"context_line":"        # Once we rollback, the snapshot is no longer needed, so remove it"},{"line_number":7054,"context_line":"        if backend.CAN_SNAPSHOT:"},{"line_number":7055,"context_line":"            backend.rollback_to_snap(utils.RESIZE_SNAPSHOT_NAME)"},{"line_number":7056,"context_line":"            backend.remove_snap(utils.RESIZE_SNAPSHOT_NAME)"},{"line_number":7057,"context_line":""},{"line_number":7058,"context_line":"        disk_info \u003d blockinfo.get_disk_info(CONF.libvirt.virt_type,"}],"source_content_type":"text/x-python","patch_set":42,"id":"da6ed579_54789f8f","line":7055,"range":{"start_line":7055,"start_character":20,"end_line":7055,"end_character":36},"updated":"2016-01-16 18:48:46.000000000","message":"I still think we want a 1-release try/except for SnapshotNotFound here and log it as a warning, with a note to remove it in newton. This is for the case of a pending resize from liberty that is reverted after upgrading the code to mitaka, it will fail because of the SnapshotNotFound.","commit_id":"b0ad491ec1abae2c5cbbe6e6d98d90b4abbb9b3f"},{"author":{"_account_id":5280,"name":"Nicolas Simonds","email":"nic@metacloud.com","username":"nicolas.simonds"},"change_message_id":"f46920799f375a23b4e37e0adbb54e1f14f7b320","unresolved":false,"context_lines":[{"line_number":7052,"context_line":"        backend \u003d self.image_backend.image(instance, \u0027disk\u0027)"},{"line_number":7053,"context_line":"        # Once we rollback, the snapshot is no longer needed, so remove it"},{"line_number":7054,"context_line":"        if backend.CAN_SNAPSHOT:"},{"line_number":7055,"context_line":"            backend.rollback_to_snap(utils.RESIZE_SNAPSHOT_NAME)"},{"line_number":7056,"context_line":"            backend.remove_snap(utils.RESIZE_SNAPSHOT_NAME)"},{"line_number":7057,"context_line":""},{"line_number":7058,"context_line":"        disk_info \u003d blockinfo.get_disk_info(CONF.libvirt.virt_type,"}],"source_content_type":"text/x-python","patch_set":42,"id":"da6ed579_3972ad7d","line":7055,"range":{"start_line":7055,"start_character":20,"end_line":7055,"end_character":36},"in_reply_to":"da6ed579_54789f8f","updated":"2016-01-18 07:06:44.000000000","message":"Done","commit_id":"b0ad491ec1abae2c5cbbe6e6d98d90b4abbb9b3f"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"117dfa9ccc9198a80ecb267ebc96bfcaf40ca71f","unresolved":false,"context_lines":[{"line_number":7068,"context_line":"        # that problems throw errors, like they should."},{"line_number":7069,"context_line":"        try:"},{"line_number":7070,"context_line":"            backend.rollback_to_snap(libvirt_utils.RESIZE_SNAPSHOT_NAME)"},{"line_number":7071,"context_line":"        except exception.SnapshotNotFound:"},{"line_number":7072,"context_line":"            LOG.warning(_LW(\"Failed to rollback snapshot (%s)\"),"},{"line_number":7073,"context_line":"                        libvirt_utils.RESIZE_SNAPSHOT_NAME)"},{"line_number":7074,"context_line":"        finally:"}],"source_content_type":"text/x-python","patch_set":43,"id":"ba63e191_52aa0172","line":7071,"range":{"start_line":7071,"start_character":8,"end_line":7071,"end_character":41},"updated":"2016-01-18 19:58:04.000000000","message":"I don\u0027t see a unit test for this case. I think you could basically take the one you have, and just have 2 side_effects to the rollback_to_snap call, the first is None and the 2nd is it raises SnapshotNotFound, but in both cases the test doesn\u0027t fail (no exception is raised up).","commit_id":"17e2cecaaaafa6f3b6b141db7d0a02325b982947"}],"nova/virt/libvirt/imagebackend.py":[{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"1db548eb63a9722d0ca3bfc1e3d40326b2708e0d","unresolved":false,"context_lines":[{"line_number":92,"context_line":"class Image(object):"},{"line_number":93,"context_line":""},{"line_number":94,"context_line":"    SUPPORTS_CLONE \u003d False"},{"line_number":95,"context_line":"    CAN_SNAPSHOT \u003d False"},{"line_number":96,"context_line":""},{"line_number":97,"context_line":"    def __init__(self, source_type, driver_format, is_block_dev\u003dFalse):"},{"line_number":98,"context_line":"        \"\"\"Image initialization."}],"source_content_type":"text/x-python","patch_set":39,"id":"da6ed579_a9475d76","line":95,"range":{"start_line":95,"start_character":4,"end_line":95,"end_character":16},"updated":"2016-01-15 20:05:02.000000000","message":"I guess this is following a pattern, but it\u0027s kind of ugly IMO.\n\nThis makes no indication to the calling code what methods should be available on the image backend to call.\n\nWhy not define the create/remove/rollback_to/_snap methods in the base class and just make them no-op and pass?  Then the rbd sub-class will implement them.\n\nThen the libvirt driver can call them and for everything but rbd they don\u0027t do anything.\n\nThis just seems kind of a hokey construct for knowing if a type of backend impl can perform some operations (oh how I miss Java interfaces for typing capability). On that note, you could also define a mixin class and then check isinstance in the libvirt driver - but that\u0027s also kind of gross (basically the same as checking the CAN_SNAPSHOT flag). I\u0027d vote for just defining the methods in the base class and making them no-ops by default.","commit_id":"459f564ea6aa603f7667e150f302efc9f51c6441"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"a7158044f714966fbcfcc6adc3a7bbf43823a762","unresolved":false,"context_lines":[{"line_number":92,"context_line":"class Image(object):"},{"line_number":93,"context_line":""},{"line_number":94,"context_line":"    SUPPORTS_CLONE \u003d False"},{"line_number":95,"context_line":"    CAN_SNAPSHOT \u003d False"},{"line_number":96,"context_line":""},{"line_number":97,"context_line":"    def __init__(self, source_type, driver_format, is_block_dev\u003dFalse):"},{"line_number":98,"context_line":"        \"\"\"Image initialization."}],"source_content_type":"text/x-python","patch_set":39,"id":"da6ed579_e0f551cb","line":95,"range":{"start_line":95,"start_character":4,"end_line":95,"end_character":16},"in_reply_to":"da6ed579_5dfbed47","updated":"2016-01-16 14:41:20.000000000","message":"I\u0027d be fine with cleaning up SUPPORTS_CLONE in a later unrelated change, but for now I don\u0027t think we should keep doing this, just put the 3  methods in the base class and make them no-ops and then implement them in the rbd image class. That\u0027s much cleaner IMO.","commit_id":"459f564ea6aa603f7667e150f302efc9f51c6441"},{"author":{"_account_id":5280,"name":"Nicolas Simonds","email":"nic@metacloud.com","username":"nicolas.simonds"},"change_message_id":"f6cf8ea8b36518e5817502218a18d9b4fbb3f3ce","unresolved":false,"context_lines":[{"line_number":92,"context_line":"class Image(object):"},{"line_number":93,"context_line":""},{"line_number":94,"context_line":"    SUPPORTS_CLONE \u003d False"},{"line_number":95,"context_line":"    CAN_SNAPSHOT \u003d False"},{"line_number":96,"context_line":""},{"line_number":97,"context_line":"    def __init__(self, source_type, driver_format, is_block_dev\u003dFalse):"},{"line_number":98,"context_line":"        \"\"\"Image initialization."}],"source_content_type":"text/x-python","patch_set":39,"id":"da6ed579_5dfbed47","line":95,"range":{"start_line":95,"start_character":4,"end_line":95,"end_character":16},"in_reply_to":"da6ed579_a9475d76","updated":"2016-01-16 07:14:59.000000000","message":"Monkey see, monkey do.  I took the SUPPORTS_CLONE attribute as prior art, held my nose, and parroted it under the auspice that this was how the imagebackend wanted to do things.\n\nBut it is following a pattern.  If you don\u0027t like the pattern, would you be amenable to a follow-on patch to tear out SUPPORTS_CLONE and CAN_SNAPSHOT and replaces them with base-class-plus-overrides?  There\u0027s already enough multiple-personality-disorder in the Nova codebase, I\u0027d like to avoid contributing to the problem if I can.","commit_id":"459f564ea6aa603f7667e150f302efc9f51c6441"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"78946a88831a7b8dc880bb0ea58817d9e391fa36","unresolved":false,"context_lines":[{"line_number":92,"context_line":"class Image(object):"},{"line_number":93,"context_line":""},{"line_number":94,"context_line":"    SUPPORTS_CLONE \u003d False"},{"line_number":95,"context_line":"    CAN_SNAPSHOT \u003d False"},{"line_number":96,"context_line":""},{"line_number":97,"context_line":"    def __init__(self, source_type, driver_format, is_block_dev\u003dFalse):"},{"line_number":98,"context_line":"        \"\"\"Image initialization."}],"source_content_type":"text/x-python","patch_set":42,"id":"da6ed579_549f3fb4","line":95,"range":{"start_line":95,"start_character":4,"end_line":95,"end_character":16},"updated":"2016-01-16 18:48:46.000000000","message":"I still don\u0027t like this, see reply in PS39. We should define the 3 snapshot methods in the base class and just make them no-ops, and then implement them in the rbd image backend sub-class.  And the driver can call them w/o the conditional. SUPPORTS_CLONE is hairier and could be dealt with separately later - or not at all, I just don\u0027t want to keep doing stuff like this.","commit_id":"b0ad491ec1abae2c5cbbe6e6d98d90b4abbb9b3f"},{"author":{"_account_id":5280,"name":"Nicolas Simonds","email":"nic@metacloud.com","username":"nicolas.simonds"},"change_message_id":"f46920799f375a23b4e37e0adbb54e1f14f7b320","unresolved":false,"context_lines":[{"line_number":92,"context_line":"class Image(object):"},{"line_number":93,"context_line":""},{"line_number":94,"context_line":"    SUPPORTS_CLONE \u003d False"},{"line_number":95,"context_line":"    CAN_SNAPSHOT \u003d False"},{"line_number":96,"context_line":""},{"line_number":97,"context_line":"    def __init__(self, source_type, driver_format, is_block_dev\u003dFalse):"},{"line_number":98,"context_line":"        \"\"\"Image initialization."}],"source_content_type":"text/x-python","patch_set":42,"id":"da6ed579_1969e98b","line":95,"range":{"start_line":95,"start_character":4,"end_line":95,"end_character":16},"in_reply_to":"da6ed579_549f3fb4","updated":"2016-01-18 07:06:44.000000000","message":"Done","commit_id":"b0ad491ec1abae2c5cbbe6e6d98d90b4abbb9b3f"}],"nova/virt/libvirt/storage/rbd_utils.py":[{"author":{"_account_id":1107,"name":"Josh Durgin","email":"jdurgin@redhat.com","username":"jdurgin"},"change_message_id":"ea74157123dfe1cca9c471984a71c4d3cd322153","unresolved":false,"context_lines":[{"line_number":367,"context_line":"            if name in [snap.get(\u0027name\u0027, \u0027\u0027) for snap in vol.list_snaps()]:"},{"line_number":368,"context_line":"                LOG.debug(\u0027rolling back rbd image(%(img)s) to\u0027"},{"line_number":369,"context_line":"                          \u0027snapshot(%(snap)s)\u0027, {\u0027snap\u0027: name, \u0027img\u0027: volume})"},{"line_number":370,"context_line":"                vol.rollback_to_snap(name)"},{"line_number":371,"context_line":"            else:"},{"line_number":372,"context_line":"                raise exception.MigrationError("},{"line_number":373,"context_line":"                    reason\u003d_(\u0027no snapshot(%(snap)s) found on image(%(img)s); \u0027"}],"source_content_type":"text/x-python","patch_set":32,"id":"ba15a1d1_2f4c8fc6","line":370,"updated":"2015-09-14 20:02:20.000000000","message":"this is a long-running operation (linear in disk size) so it should be run under tpool.execute()","commit_id":"bcdd67cff90100bab9a5cb5fbba34e99bd1a2ae7"},{"author":{"_account_id":5280,"name":"Nicolas Simonds","email":"nic@metacloud.com","username":"nicolas.simonds"},"change_message_id":"b3a031c2bc4e58ed091d19658ed2b17e77499181","unresolved":false,"context_lines":[{"line_number":367,"context_line":"            if name in [snap.get(\u0027name\u0027, \u0027\u0027) for snap in vol.list_snaps()]:"},{"line_number":368,"context_line":"                LOG.debug(\u0027rolling back rbd image(%(img)s) to\u0027"},{"line_number":369,"context_line":"                          \u0027snapshot(%(snap)s)\u0027, {\u0027snap\u0027: name, \u0027img\u0027: volume})"},{"line_number":370,"context_line":"                vol.rollback_to_snap(name)"},{"line_number":371,"context_line":"            else:"},{"line_number":372,"context_line":"                raise exception.MigrationError("},{"line_number":373,"context_line":"                    reason\u003d_(\u0027no snapshot(%(snap)s) found on image(%(img)s); \u0027"}],"source_content_type":"text/x-python","patch_set":32,"id":"ba15a1d1_46cf6556","line":370,"in_reply_to":"ba15a1d1_2f4c8fc6","updated":"2015-09-15 01:04:58.000000000","message":"Done.\n\nUpsold all of the snapshot-related methods to use tpool.execute(), because sometimes Ceph takes its time completing these operations, and it shouldn\u0027t brick n-cpu when it does.","commit_id":"bcdd67cff90100bab9a5cb5fbba34e99bd1a2ae7"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"1db548eb63a9722d0ca3bfc1e3d40326b2708e0d","unresolved":false,"context_lines":[{"line_number":286,"context_line":"                rbd.RBD().remove(client.ioctx, volume)"},{"line_number":287,"context_line":"                raise loopingcall.LoopingCallDone(retvalue\u003dFalse)"},{"line_number":288,"context_line":"            except rbd.ImageHasSnapshots:"},{"line_number":289,"context_line":"                self.remove_snap(volume, \u0027nova-resize\u0027, ignore_errors\u003dTrue)"},{"line_number":290,"context_line":"            except (rbd.ImageBusy, rbd.ImageHasSnapshots):"},{"line_number":291,"context_line":"                LOG.warn(_LW(\u0027rbd remove %(volume)s in pool %(pool)s \u0027"},{"line_number":292,"context_line":"                             \u0027failed\u0027),"}],"source_content_type":"text/x-python","patch_set":39,"id":"da6ed579_ecbfa35e","line":289,"range":{"start_line":289,"start_character":41,"end_line":289,"end_character":54},"updated":"2016-01-15 20:05:02.000000000","message":"We should probably make this a constant somewhere since it\u0027s being used here and in the libvirt driver, thus tight coupling in all it\u0027s glory.","commit_id":"459f564ea6aa603f7667e150f302efc9f51c6441"},{"author":{"_account_id":5280,"name":"Nicolas Simonds","email":"nic@metacloud.com","username":"nicolas.simonds"},"change_message_id":"f6cf8ea8b36518e5817502218a18d9b4fbb3f3ce","unresolved":false,"context_lines":[{"line_number":286,"context_line":"                rbd.RBD().remove(client.ioctx, volume)"},{"line_number":287,"context_line":"                raise loopingcall.LoopingCallDone(retvalue\u003dFalse)"},{"line_number":288,"context_line":"            except rbd.ImageHasSnapshots:"},{"line_number":289,"context_line":"                self.remove_snap(volume, \u0027nova-resize\u0027, ignore_errors\u003dTrue)"},{"line_number":290,"context_line":"            except (rbd.ImageBusy, rbd.ImageHasSnapshots):"},{"line_number":291,"context_line":"                LOG.warn(_LW(\u0027rbd remove %(volume)s in pool %(pool)s \u0027"},{"line_number":292,"context_line":"                             \u0027failed\u0027),"}],"source_content_type":"text/x-python","patch_set":39,"id":"da6ed579_1d9495e6","line":289,"range":{"start_line":289,"start_character":41,"end_line":289,"end_character":54},"in_reply_to":"da6ed579_ecbfa35e","updated":"2016-01-16 07:14:59.000000000","message":"Done","commit_id":"459f564ea6aa603f7667e150f302efc9f51c6441"},{"author":{"_account_id":18247,"name":"Mark Doffman","email":"mdoffman@linux.vnet.ibm.com","username":"doffm"},"change_message_id":"15dd45927436ef2ade69c980784ebe807d0ac44d","unresolved":false,"context_lines":[{"line_number":304,"context_line":"                # filter out non-ephemerals from the list"},{"line_number":305,"context_line":"                if instance.task_state \u003d\u003d task_states.RESIZE_REVERTING:"},{"line_number":306,"context_line":"                    return (disk.startswith(instance.uuid) and"},{"line_number":307,"context_line":"                            disk.endswith(\u0027disk.local\u0027))"},{"line_number":308,"context_line":"                else:"},{"line_number":309,"context_line":"                    return disk.startswith(instance.uuid)"},{"line_number":310,"context_line":""}],"source_content_type":"text/x-python","patch_set":39,"id":"da6ed579_bd15574a","line":307,"range":{"start_line":307,"start_character":53,"end_line":307,"end_character":56},"updated":"2016-01-15 21:25:55.000000000","message":"This method isn\u0027t called when cleaning up on \u0027revert_resize\u0027. So I don\u0027t understand the purpose of this logic. When doing \u0027cleanup_volumes\u0027 we want to remove all volumes that are owned by the instance. What issue is this fixing?","commit_id":"459f564ea6aa603f7667e150f302efc9f51c6441"},{"author":{"_account_id":5280,"name":"Nicolas Simonds","email":"nic@metacloud.com","username":"nicolas.simonds"},"change_message_id":"2d6ec70538fa2b7b5c6167f7ebeef1036dfebe1c","unresolved":false,"context_lines":[{"line_number":304,"context_line":"                # filter out non-ephemerals from the list"},{"line_number":305,"context_line":"                if instance.task_state \u003d\u003d task_states.RESIZE_REVERTING:"},{"line_number":306,"context_line":"                    return (disk.startswith(instance.uuid) and"},{"line_number":307,"context_line":"                            disk.endswith(\u0027disk.local\u0027))"},{"line_number":308,"context_line":"                else:"},{"line_number":309,"context_line":"                    return disk.startswith(instance.uuid)"},{"line_number":310,"context_line":""}],"source_content_type":"text/x-python","patch_set":39,"id":"da6ed579_783b6d39","line":307,"range":{"start_line":307,"start_character":53,"end_line":307,"end_character":56},"in_reply_to":"da6ed579_bd15574a","updated":"2016-01-15 21:42:12.000000000","message":"This is destroying any extant resize snapshots on the image in the case of instance termination, i.e., user initiates a resize, and instead of confirming it, they terminate the instance.\n\nIt\u0027s more common than you would think.","commit_id":"459f564ea6aa603f7667e150f302efc9f51c6441"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"1db548eb63a9722d0ca3bfc1e3d40326b2708e0d","unresolved":false,"context_lines":[{"line_number":355,"context_line":"                tpool.execute(vol.remove_snap, name)"},{"line_number":356,"context_line":"            else:"},{"line_number":357,"context_line":"                if not ignore_errors:"},{"line_number":358,"context_line":"                    LOG.warn(_LW(\u0027no snapshot(%(snap)s) found on\u0027"},{"line_number":359,"context_line":"                                 \u0027image(%(img)s)\u0027), {\u0027snap\u0027: name,"},{"line_number":360,"context_line":"                                                     \u0027img\u0027: volume})"},{"line_number":361,"context_line":""}],"source_content_type":"text/x-python","patch_set":39,"id":"da6ed579_ac0f6b87","line":358,"range":{"start_line":358,"start_character":24,"end_line":358,"end_character":28},"updated":"2016-01-15 20:05:02.000000000","message":"This should probably be warning for py3 compat.","commit_id":"459f564ea6aa603f7667e150f302efc9f51c6441"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"45dc1d3701cd2b127a035eeae5d0563a0d1fa296","unresolved":false,"context_lines":[{"line_number":355,"context_line":"                tpool.execute(vol.remove_snap, name)"},{"line_number":356,"context_line":"            else:"},{"line_number":357,"context_line":"                if not ignore_errors:"},{"line_number":358,"context_line":"                    LOG.warn(_LW(\u0027no snapshot(%(snap)s) found on\u0027"},{"line_number":359,"context_line":"                                 \u0027image(%(img)s)\u0027), {\u0027snap\u0027: name,"},{"line_number":360,"context_line":"                                                     \u0027img\u0027: volume})"},{"line_number":361,"context_line":""}],"source_content_type":"text/x-python","patch_set":39,"id":"da6ed579_ef15559b","line":358,"range":{"start_line":358,"start_character":62,"end_line":358,"end_character":64},"updated":"2016-01-15 20:23:14.000000000","message":"space between \u0027on\u0027 and \u0027image\u0027.","commit_id":"459f564ea6aa603f7667e150f302efc9f51c6441"},{"author":{"_account_id":5280,"name":"Nicolas Simonds","email":"nic@metacloud.com","username":"nicolas.simonds"},"change_message_id":"f6cf8ea8b36518e5817502218a18d9b4fbb3f3ce","unresolved":false,"context_lines":[{"line_number":355,"context_line":"                tpool.execute(vol.remove_snap, name)"},{"line_number":356,"context_line":"            else:"},{"line_number":357,"context_line":"                if not ignore_errors:"},{"line_number":358,"context_line":"                    LOG.warn(_LW(\u0027no snapshot(%(snap)s) found on\u0027"},{"line_number":359,"context_line":"                                 \u0027image(%(img)s)\u0027), {\u0027snap\u0027: name,"},{"line_number":360,"context_line":"                                                     \u0027img\u0027: volume})"},{"line_number":361,"context_line":""}],"source_content_type":"text/x-python","patch_set":39,"id":"da6ed579_3d995920","line":358,"range":{"start_line":358,"start_character":24,"end_line":358,"end_character":28},"in_reply_to":"da6ed579_ac0f6b87","updated":"2016-01-16 07:14:59.000000000","message":"Done","commit_id":"459f564ea6aa603f7667e150f302efc9f51c6441"},{"author":{"_account_id":5280,"name":"Nicolas Simonds","email":"nic@metacloud.com","username":"nicolas.simonds"},"change_message_id":"f6cf8ea8b36518e5817502218a18d9b4fbb3f3ce","unresolved":false,"context_lines":[{"line_number":355,"context_line":"                tpool.execute(vol.remove_snap, name)"},{"line_number":356,"context_line":"            else:"},{"line_number":357,"context_line":"                if not ignore_errors:"},{"line_number":358,"context_line":"                    LOG.warn(_LW(\u0027no snapshot(%(snap)s) found on\u0027"},{"line_number":359,"context_line":"                                 \u0027image(%(img)s)\u0027), {\u0027snap\u0027: name,"},{"line_number":360,"context_line":"                                                     \u0027img\u0027: volume})"},{"line_number":361,"context_line":""}],"source_content_type":"text/x-python","patch_set":39,"id":"da6ed579_dd9d9d0b","line":358,"range":{"start_line":358,"start_character":62,"end_line":358,"end_character":64},"in_reply_to":"da6ed579_ef15559b","updated":"2016-01-16 07:14:59.000000000","message":"Done","commit_id":"459f564ea6aa603f7667e150f302efc9f51c6441"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"45dc1d3701cd2b127a035eeae5d0563a0d1fa296","unresolved":false,"context_lines":[{"line_number":367,"context_line":"        \"\"\""},{"line_number":368,"context_line":"        with RBDVolumeProxy(self, volume) as vol:"},{"line_number":369,"context_line":"            if name in [snap.get(\u0027name\u0027, \u0027\u0027) for snap in vol.list_snaps()]:"},{"line_number":370,"context_line":"                LOG.debug(\u0027rolling back rbd image(%(img)s) to\u0027"},{"line_number":371,"context_line":"                          \u0027snapshot(%(snap)s)\u0027, {\u0027snap\u0027: name, \u0027img\u0027: volume})"},{"line_number":372,"context_line":"                tpool.execute(vol.rollback_to_snap, name)"},{"line_number":373,"context_line":"            else:"}],"source_content_type":"text/x-python","patch_set":39,"id":"da6ed579_cf1091ae","line":370,"range":{"start_line":370,"start_character":59,"end_line":370,"end_character":61},"updated":"2016-01-15 20:23:14.000000000","message":"Need a space between \u0027to\u0027 and \u0027snapshot\u0027 here.","commit_id":"459f564ea6aa603f7667e150f302efc9f51c6441"},{"author":{"_account_id":5280,"name":"Nicolas Simonds","email":"nic@metacloud.com","username":"nicolas.simonds"},"change_message_id":"f6cf8ea8b36518e5817502218a18d9b4fbb3f3ce","unresolved":false,"context_lines":[{"line_number":367,"context_line":"        \"\"\""},{"line_number":368,"context_line":"        with RBDVolumeProxy(self, volume) as vol:"},{"line_number":369,"context_line":"            if name in [snap.get(\u0027name\u0027, \u0027\u0027) for snap in vol.list_snaps()]:"},{"line_number":370,"context_line":"                LOG.debug(\u0027rolling back rbd image(%(img)s) to\u0027"},{"line_number":371,"context_line":"                          \u0027snapshot(%(snap)s)\u0027, {\u0027snap\u0027: name, \u0027img\u0027: volume})"},{"line_number":372,"context_line":"                tpool.execute(vol.rollback_to_snap, name)"},{"line_number":373,"context_line":"            else:"}],"source_content_type":"text/x-python","patch_set":39,"id":"da6ed579_fda2e14a","line":370,"range":{"start_line":370,"start_character":59,"end_line":370,"end_character":61},"in_reply_to":"da6ed579_cf1091ae","updated":"2016-01-16 07:14:59.000000000","message":"Done","commit_id":"459f564ea6aa603f7667e150f302efc9f51c6441"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"1db548eb63a9722d0ca3bfc1e3d40326b2708e0d","unresolved":false,"context_lines":[{"line_number":371,"context_line":"                          \u0027snapshot(%(snap)s)\u0027, {\u0027snap\u0027: name, \u0027img\u0027: volume})"},{"line_number":372,"context_line":"                tpool.execute(vol.rollback_to_snap, name)"},{"line_number":373,"context_line":"            else:"},{"line_number":374,"context_line":"                raise exception.MigrationError("},{"line_number":375,"context_line":"                    reason\u003d_(\u0027no snapshot(%(snap)s) found on image(%(img)s); \u0027"},{"line_number":376,"context_line":"                             \u0027cannot rollback\u0027) %"},{"line_number":377,"context_line":"                           {\u0027snap\u0027: name, \u0027img\u0027: volume})"}],"source_content_type":"text/x-python","patch_set":39,"id":"da6ed579_ac3e8bd8","line":374,"range":{"start_line":374,"start_character":32,"end_line":374,"end_character":46},"updated":"2016-01-15 20:05:02.000000000","message":"This assumes you\u0027re doing a migration, which you are in this patch, but when someone builds on this they might not be in a migration operation. I\u0027d recommend using exception.SnapshotNotFound here.","commit_id":"459f564ea6aa603f7667e150f302efc9f51c6441"},{"author":{"_account_id":5280,"name":"Nicolas Simonds","email":"nic@metacloud.com","username":"nicolas.simonds"},"change_message_id":"f6cf8ea8b36518e5817502218a18d9b4fbb3f3ce","unresolved":false,"context_lines":[{"line_number":371,"context_line":"                          \u0027snapshot(%(snap)s)\u0027, {\u0027snap\u0027: name, \u0027img\u0027: volume})"},{"line_number":372,"context_line":"                tpool.execute(vol.rollback_to_snap, name)"},{"line_number":373,"context_line":"            else:"},{"line_number":374,"context_line":"                raise exception.MigrationError("},{"line_number":375,"context_line":"                    reason\u003d_(\u0027no snapshot(%(snap)s) found on image(%(img)s); \u0027"},{"line_number":376,"context_line":"                             \u0027cannot rollback\u0027) %"},{"line_number":377,"context_line":"                           {\u0027snap\u0027: name, \u0027img\u0027: volume})"}],"source_content_type":"text/x-python","patch_set":39,"id":"da6ed579_9d8885c8","line":374,"range":{"start_line":374,"start_character":32,"end_line":374,"end_character":46},"in_reply_to":"da6ed579_ac3e8bd8","updated":"2016-01-16 07:14:59.000000000","message":"Done","commit_id":"459f564ea6aa603f7667e150f302efc9f51c6441"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"78946a88831a7b8dc880bb0ea58817d9e391fa36","unresolved":false,"context_lines":[{"line_number":285,"context_line":"            try:"},{"line_number":286,"context_line":"                rbd.RBD().remove(client.ioctx, volume)"},{"line_number":287,"context_line":"                raise loopingcall.LoopingCallDone(retvalue\u003dFalse)"},{"line_number":288,"context_line":"            except rbd.ImageHasSnapshots:"},{"line_number":289,"context_line":"                self.remove_snap(volume, utils.RESIZE_SNAPSHOT_NAME,"},{"line_number":290,"context_line":"                                 ignore_errors\u003dTrue)"},{"line_number":291,"context_line":"            except (rbd.ImageBusy, rbd.ImageHasSnapshots):"}],"source_content_type":"text/x-python","patch_set":42,"id":"da6ed579_b4aebbe5","line":288,"range":{"start_line":288,"start_character":12,"end_line":288,"end_character":40},"updated":"2016-01-16 18:48:46.000000000","message":"I don\u0027t see a unit test for this case.","commit_id":"b0ad491ec1abae2c5cbbe6e6d98d90b4abbb9b3f"},{"author":{"_account_id":5280,"name":"Nicolas Simonds","email":"nic@metacloud.com","username":"nicolas.simonds"},"change_message_id":"f46920799f375a23b4e37e0adbb54e1f14f7b320","unresolved":false,"context_lines":[{"line_number":285,"context_line":"            try:"},{"line_number":286,"context_line":"                rbd.RBD().remove(client.ioctx, volume)"},{"line_number":287,"context_line":"                raise loopingcall.LoopingCallDone(retvalue\u003dFalse)"},{"line_number":288,"context_line":"            except rbd.ImageHasSnapshots:"},{"line_number":289,"context_line":"                self.remove_snap(volume, utils.RESIZE_SNAPSHOT_NAME,"},{"line_number":290,"context_line":"                                 ignore_errors\u003dTrue)"},{"line_number":291,"context_line":"            except (rbd.ImageBusy, rbd.ImageHasSnapshots):"}],"source_content_type":"text/x-python","patch_set":42,"id":"da6ed579_d67d60e8","line":288,"range":{"start_line":288,"start_character":12,"end_line":288,"end_character":40},"in_reply_to":"da6ed579_b4aebbe5","updated":"2016-01-18 07:06:44.000000000","message":"Done","commit_id":"b0ad491ec1abae2c5cbbe6e6d98d90b4abbb9b3f"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"78946a88831a7b8dc880bb0ea58817d9e391fa36","unresolved":false,"context_lines":[{"line_number":303,"context_line":"                # volume are handled with an \"rbd snap rollback\" command,"},{"line_number":304,"context_line":"                # and none of this is needed (and is, in fact, harmful) so"},{"line_number":305,"context_line":"                # filter out non-ephemerals from the list"},{"line_number":306,"context_line":"                if instance.task_state \u003d\u003d task_states.RESIZE_REVERTING:"},{"line_number":307,"context_line":"                    return (disk.startswith(instance.uuid) and"},{"line_number":308,"context_line":"                            disk.endswith(\u0027disk.local\u0027))"},{"line_number":309,"context_line":"                else:"}],"source_content_type":"text/x-python","patch_set":42,"id":"da6ed579_d4ab2fd5","line":306,"range":{"start_line":306,"start_character":16,"end_line":306,"end_character":70},"updated":"2016-01-16 18:48:46.000000000","message":"I don\u0027t see a unit test for this case.","commit_id":"b0ad491ec1abae2c5cbbe6e6d98d90b4abbb9b3f"},{"author":{"_account_id":5280,"name":"Nicolas Simonds","email":"nic@metacloud.com","username":"nicolas.simonds"},"change_message_id":"f46920799f375a23b4e37e0adbb54e1f14f7b320","unresolved":false,"context_lines":[{"line_number":303,"context_line":"                # volume are handled with an \"rbd snap rollback\" command,"},{"line_number":304,"context_line":"                # and none of this is needed (and is, in fact, harmful) so"},{"line_number":305,"context_line":"                # filter out non-ephemerals from the list"},{"line_number":306,"context_line":"                if instance.task_state \u003d\u003d task_states.RESIZE_REVERTING:"},{"line_number":307,"context_line":"                    return (disk.startswith(instance.uuid) and"},{"line_number":308,"context_line":"                            disk.endswith(\u0027disk.local\u0027))"},{"line_number":309,"context_line":"                else:"}],"source_content_type":"text/x-python","patch_set":42,"id":"da6ed579_d96271ad","line":306,"range":{"start_line":306,"start_character":16,"end_line":306,"end_character":70},"in_reply_to":"da6ed579_d4ab2fd5","updated":"2016-01-18 07:06:44.000000000","message":"Done","commit_id":"b0ad491ec1abae2c5cbbe6e6d98d90b4abbb9b3f"}]}
