Improve migration_get_progress error handling
Share manager may raise InvalidShare because the migration phase has already been completed. In such cases total_progress 100 can be reported instead of raising ShareMigrationError. Change-Id: I6e1b1abf6a2fd8c1268e446b7ee8e364bdc496bc Closes-Bug: #1889549
This commit is contained in:
parent
5f433b59ba
commit
fec7643a85
@ -1565,6 +1565,10 @@ class API(base.Base):
|
|||||||
try:
|
try:
|
||||||
result = self.share_rpcapi.migration_get_progress(
|
result = self.share_rpcapi.migration_get_progress(
|
||||||
context, share_instance_ref, migrating_instance_id)
|
context, share_instance_ref, migrating_instance_id)
|
||||||
|
except exception.InvalidShare:
|
||||||
|
# reload to get the latest task_state
|
||||||
|
share = self.db.share_get(context, share['id'])
|
||||||
|
result = self._migration_get_progress_state(share)
|
||||||
except Exception:
|
except Exception:
|
||||||
msg = _("Failed to obtain migration progress of share "
|
msg = _("Failed to obtain migration progress of share "
|
||||||
"%s.") % share['id']
|
"%s.") % share['id']
|
||||||
|
@ -5513,6 +5513,41 @@ class ShareAPITestCase(test.TestCase):
|
|||||||
mock_get_destination.assert_called_once_with(
|
mock_get_destination.assert_called_once_with(
|
||||||
self.context, 'fake_src_server_id', status=constants.STATUS_ACTIVE)
|
self.context, 'fake_src_server_id', status=constants.STATUS_ACTIVE)
|
||||||
|
|
||||||
|
def test_migration_get_progress_race(self):
|
||||||
|
|
||||||
|
instance1 = db_utils.create_share_instance(
|
||||||
|
share_id='fake_id',
|
||||||
|
status=constants.STATUS_MIGRATING,
|
||||||
|
host='some_host')
|
||||||
|
instance2 = db_utils.create_share_instance(
|
||||||
|
share_id='fake_id',
|
||||||
|
status=constants.STATUS_MIGRATING_TO)
|
||||||
|
share = db_utils.create_share(
|
||||||
|
id='fake_id',
|
||||||
|
task_state=constants.TASK_STATE_MIGRATION_DRIVER_IN_PROGRESS,
|
||||||
|
instances=[instance1, instance2])
|
||||||
|
share_ref = fakes.fake_share(
|
||||||
|
id='fake_id',
|
||||||
|
task_state=constants.TASK_STATE_MIGRATION_DRIVER_PHASE1_DONE)
|
||||||
|
service = 'fake_service'
|
||||||
|
expected = {'total_progress': 100}
|
||||||
|
|
||||||
|
self.mock_object(utils, 'service_is_up', mock.Mock(return_value=True))
|
||||||
|
self.mock_object(db_api, 'service_get_by_args',
|
||||||
|
mock.Mock(return_value=service))
|
||||||
|
self.mock_object(db_api, 'share_instance_get',
|
||||||
|
mock.Mock(return_value=instance1))
|
||||||
|
self.mock_object(db_api, 'share_get',
|
||||||
|
mock.Mock(return_value=share_ref))
|
||||||
|
self.mock_object(self.api.share_rpcapi, 'migration_get_progress',
|
||||||
|
mock.Mock(side_effect=exception.InvalidShare('fake')))
|
||||||
|
|
||||||
|
result = self.api.migration_get_progress(self.context, share)
|
||||||
|
self.assertEqual(expected, result)
|
||||||
|
|
||||||
|
self.api.share_rpcapi.migration_get_progress.assert_called_once_with(
|
||||||
|
self.context, instance1, instance2['id'])
|
||||||
|
|
||||||
|
|
||||||
class OtherTenantsShareActionsTestCase(test.TestCase):
|
class OtherTenantsShareActionsTestCase(test.TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
fixes:
|
||||||
|
- |
|
||||||
|
In the share migration_get_progress API a race condition was fixed. If the
|
||||||
|
share manager reports ``InvalidShare`` the share's task state is evaluated
|
||||||
|
again to return progress 0 or 100 based on known task states instead of
|
||||||
|
raising ``ShareMigrationError``.
|
Loading…
Reference in New Issue
Block a user