Merge "Fix: Online migration for volume_use_quota_online_data_migration"

This commit is contained in:
Zuul 2021-09-15 17:22:52 +00:00 committed by Gerrit Code Review
commit 2d86e247f9
3 changed files with 29 additions and 9 deletions

View File

@ -1944,12 +1944,12 @@ def conditional_update(context, model, values, expected_values, filters=(),
# TODO: (Y Release) remove method and this comment
def volume_use_quota_online_data_migration(context, max_count):
IMPL.volume_use_quota_online_data_migration(context, max_count)
return IMPL.volume_use_quota_online_data_migration(context, max_count)
# TODO: (Y Release) remove method and this comment
def snapshot_use_quota_online_data_migration(context, max_count):
IMPL.snapshot_use_quota_online_data_migration(context, max_count)
return IMPL.snapshot_use_quota_online_data_migration(context, max_count)
# TODO: (Z Release) remove method and this comment

View File

@ -7395,8 +7395,15 @@ def conditional_update(context, model, values, expected_values, filters=(),
@enginefacade.writer
def volume_use_quota_online_data_migration(context, max_count):
def calculate_use_quota(volume):
return not (volume.migration_status.startswith('target:') or
volume.admin_metadata.get('temporary') == 'True')
is_migrating = (volume.migration_status or '').startswith('target:')
is_temporary = False
if volume.volume_admin_metadata:
for admin_meta in volume.volume_admin_metadata:
if (admin_meta.key == 'temporary') and (
admin_meta.value == 'True'):
is_temporary = True
break
return not (is_migrating or is_temporary)
return use_quota_online_data_migration(context, max_count, 'Volume',
calculate_use_quota)
@ -7430,6 +7437,8 @@ def use_quota_online_data_migration(context, max_count,
getattr(models, resource_name),
session=session).filter_by(
use_quota=None)
if resource_name == 'Volume':
query = query.options(joinedload('volume_admin_metadata'))
total = query.count()
resources = query.limit(max_count).with_for_update().all()
for resource in resources:

View File

@ -3858,6 +3858,11 @@ class OnlineMigrationTestCase(BaseTest):
# TODO: (Y Release) remove method and this comment
@mock.patch.object(sqlalchemy_api, 'use_quota_online_data_migration')
def test_volume_use_quota_online_data_migration(self, migration_mock):
class FakeAdminMeta:
def __init__(self, value):
self.key = 'temporary'
self.value = value
sqlalchemy_api.volume_use_quota_online_data_migration(
self.ctxt, mock.sentinel.max_count)
migration_mock.assert_called_once_with(self.ctxt,
@ -3867,15 +3872,21 @@ class OnlineMigrationTestCase(BaseTest):
calculation_method = migration_mock.call_args[0][3]
# Confirm we set use_quota field to False for temporary volumes
temp_volume = mock.Mock(admin_metadata={'temporary': True})
temp_volume = mock.Mock(volume_admin_metadata=[FakeAdminMeta('True')])
self.assertFalse(calculation_method(temp_volume))
# Confirm we set use_quota field to False for temporary volumes
migration_dest_volume = mock.Mock(migration_status='target:123')
# Confirm we set use_quota field to False for migrating volumes
migration_dest_volume = mock.Mock(migration_status='target:123',
volume_admin_metadata=[])
self.assertFalse(calculation_method(migration_dest_volume))
# Confirm we set use_quota field to False in other cases
volume = mock.Mock(admin_metadata={'temporary': False},
# Confirm we set use_quota field to True for non-migrating volumes
non_migrating_volume = mock.Mock(migration_status=None,
volume_admin_metadata=[])
self.assertTrue(calculation_method(non_migrating_volume))
# Confirm we set use_quota field to True in other cases
volume = mock.Mock(volume_admin_metadata=[FakeAdminMeta('False')],
migration_status='success')
self.assertTrue(calculation_method(volume))