Add backref relationships to ConsistencyGroup obj
ConsistencyGroup object was missing relationships that were defined on the SQLAlchemy model as backrefs. This includes volumes and cgsnapshots fields. This commit adds fields representing these relationships. Change-Id: Ia74997ddfed1e472874b6892c2fcaa208b7a9a3c Partial-Bug: 1509012
This commit is contained in:
@@ -25,8 +25,8 @@ def register_all():
|
||||
# function in order for it to be registered by services that may
|
||||
# need to receive it via RPC.
|
||||
__import__('cinder.objects.backup')
|
||||
__import__('cinder.objects.consistencygroup')
|
||||
__import__('cinder.objects.cgsnapshot')
|
||||
__import__('cinder.objects.consistencygroup')
|
||||
__import__('cinder.objects.service')
|
||||
__import__('cinder.objects.snapshot')
|
||||
__import__('cinder.objects.volume')
|
||||
|
||||
@@ -19,11 +19,15 @@ from cinder import objects
|
||||
from cinder.objects import base
|
||||
from oslo_versionedobjects import fields
|
||||
|
||||
OPTIONAL_FIELDS = ['cgsnapshots', 'volumes']
|
||||
|
||||
|
||||
@base.CinderObjectRegistry.register
|
||||
class ConsistencyGroup(base.CinderPersistentObject, base.CinderObject,
|
||||
base.CinderObjectDictCompat):
|
||||
VERSION = '1.0'
|
||||
# Version 1.0: Initial version
|
||||
# Version 1.1: Added cgsnapshots and volumes relationships
|
||||
VERSION = '1.1'
|
||||
|
||||
fields = {
|
||||
'id': fields.UUIDField(),
|
||||
@@ -37,14 +41,35 @@ class ConsistencyGroup(base.CinderPersistentObject, base.CinderObject,
|
||||
'status': fields.StringField(nullable=True),
|
||||
'cgsnapshot_id': fields.UUIDField(nullable=True),
|
||||
'source_cgid': fields.UUIDField(nullable=True),
|
||||
'cgsnapshots': fields.ObjectField('CGSnapshotList', nullable=True),
|
||||
'volumes': fields.ObjectField('VolumeList', nullable=True),
|
||||
}
|
||||
|
||||
@staticmethod
|
||||
def _from_db_object(context, consistencygroup, db_consistencygroup):
|
||||
def _from_db_object(context, consistencygroup, db_consistencygroup,
|
||||
expected_attrs=None):
|
||||
if expected_attrs is None:
|
||||
expected_attrs = []
|
||||
for name, field in consistencygroup.fields.items():
|
||||
if name in OPTIONAL_FIELDS:
|
||||
continue
|
||||
value = db_consistencygroup.get(name)
|
||||
setattr(consistencygroup, name, value)
|
||||
|
||||
if 'cgsnapshots' in expected_attrs:
|
||||
cgsnapshots = base.obj_make_list(
|
||||
context, objects.CGSnapshotsList(context),
|
||||
objects.CGSnapshot,
|
||||
db_consistencygroup['cgsnapshots'])
|
||||
consistencygroup.cgsnapshots = cgsnapshots
|
||||
|
||||
if 'volumes' in expected_attrs:
|
||||
volumes = base.obj_make_list(
|
||||
context, objects.VolumeList(context),
|
||||
objects.Volume,
|
||||
db_consistencygroup['volumes'])
|
||||
consistencygroup.cgsnapshots = volumes
|
||||
|
||||
consistencygroup._context = context
|
||||
consistencygroup.obj_reset_changes()
|
||||
return consistencygroup
|
||||
@@ -55,14 +80,49 @@ class ConsistencyGroup(base.CinderPersistentObject, base.CinderObject,
|
||||
raise exception.ObjectActionError(action='create',
|
||||
reason=_('already_created'))
|
||||
updates = self.cinder_obj_get_changes()
|
||||
|
||||
if 'cgsnapshots' in updates:
|
||||
raise exception.ObjectActionError(action='create',
|
||||
reason=_('cgsnapshots assigned'))
|
||||
|
||||
if 'volumes' in updates:
|
||||
raise exception.ObjectActionError(action='create',
|
||||
reason=_('volumes assigned'))
|
||||
|
||||
db_consistencygroups = db.consistencygroup_create(self._context,
|
||||
updates)
|
||||
self._from_db_object(self._context, self, db_consistencygroups)
|
||||
|
||||
def obj_load_attr(self, attrname):
|
||||
if attrname not in OPTIONAL_FIELDS:
|
||||
raise exception.ObjectActionError(
|
||||
action='obj_load_attr',
|
||||
reason=_('attribute %s not lazy-loadable') % attrname)
|
||||
if not self._context:
|
||||
raise exception.OrphanedObjectError(method='obj_load_attr',
|
||||
objtype=self.obj_name())
|
||||
|
||||
if attrname == 'cgsnapshots':
|
||||
self.cgsnapshots = objects.CGSnapshotList.get_all_by_group(
|
||||
self._context, self.id)
|
||||
|
||||
if attrname == 'volumes':
|
||||
self.volumes = objects.VolumeList.get_all_by_group(self._context,
|
||||
self.id)
|
||||
|
||||
self.obj_reset_changes(fields=[attrname])
|
||||
|
||||
@base.remotable
|
||||
def save(self):
|
||||
updates = self.cinder_obj_get_changes()
|
||||
if updates:
|
||||
if 'cgsnapshots' in updates:
|
||||
raise exception.ObjectActionError(
|
||||
action='save', reason=_('cgsnapshots changed'))
|
||||
if 'volumes' in updates:
|
||||
raise exception.ObjectActionError(
|
||||
action='save', reason=_('volumes changed'))
|
||||
|
||||
db.consistencygroup_update(self._context, self.id, updates)
|
||||
self.obj_reset_changes()
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ def fake_db_consistencygroup(**updates):
|
||||
'user_id': '2',
|
||||
'project_id': '3',
|
||||
'host': 'FakeHost',
|
||||
'volumes': [],
|
||||
}
|
||||
for name, field in objects.ConsistencyGroup.fields.items():
|
||||
if name in db_values:
|
||||
|
||||
@@ -32,6 +32,16 @@ fake_consistencygroup = {
|
||||
'source_cgid': None,
|
||||
}
|
||||
|
||||
fake_cgsnapshot = {
|
||||
'id': '1',
|
||||
'user_id': 'fake_user_id',
|
||||
'project_id': 'fake_project_id',
|
||||
'name': 'fake_name',
|
||||
'description': 'fake_description',
|
||||
'status': 'creating',
|
||||
'consistencygroup_id': 'fake_id',
|
||||
}
|
||||
|
||||
|
||||
class TestConsistencyGroup(test_objects.BaseObjectsTestCase):
|
||||
|
||||
@@ -74,6 +84,57 @@ class TestConsistencyGroup(test_objects.BaseObjectsTestCase):
|
||||
consistencygroup.id,
|
||||
{'status': 'active'})
|
||||
|
||||
def test_save_with_cgsnapshots(self):
|
||||
consistencygroup = objects.ConsistencyGroup._from_db_object(
|
||||
self.context, objects.ConsistencyGroup(), fake_consistencygroup)
|
||||
cgsnapshots_objs = [objects.CGSnapshot(context=self.context, id=i)
|
||||
for i in [3, 4, 5]]
|
||||
cgsnapshots = objects.CGSnapshotList(objects=cgsnapshots_objs)
|
||||
consistencygroup.name = 'foobar'
|
||||
consistencygroup.cgsnapshots = cgsnapshots
|
||||
self.assertEqual({'name': 'foobar',
|
||||
'cgsnapshots': cgsnapshots},
|
||||
consistencygroup.obj_get_changes())
|
||||
self.assertRaises(exception.ObjectActionError, consistencygroup.save)
|
||||
|
||||
def test_save_with_volumes(self):
|
||||
consistencygroup = objects.ConsistencyGroup._from_db_object(
|
||||
self.context, objects.ConsistencyGroup(), fake_consistencygroup)
|
||||
volumes_objs = [objects.Volume(context=self.context, id=i)
|
||||
for i in [3, 4, 5]]
|
||||
volumes = objects.VolumeList(objects=volumes_objs)
|
||||
consistencygroup.name = 'foobar'
|
||||
consistencygroup.volumes = volumes
|
||||
self.assertEqual({'name': 'foobar',
|
||||
'volumes': volumes},
|
||||
consistencygroup.obj_get_changes())
|
||||
self.assertRaises(exception.ObjectActionError, consistencygroup.save)
|
||||
|
||||
@mock.patch('cinder.objects.cgsnapshot.CGSnapshotList.get_all_by_group')
|
||||
@mock.patch('cinder.objects.volume.VolumeList.get_all_by_group')
|
||||
def test_obj_load_attr(self, mock_vol_get_all_by_group,
|
||||
mock_cgsnap_get_all_by_group):
|
||||
consistencygroup = objects.ConsistencyGroup._from_db_object(
|
||||
self.context, objects.ConsistencyGroup(), fake_consistencygroup)
|
||||
# Test cgsnapshots lazy-loaded field
|
||||
cgsnapshots_objs = [objects.CGSnapshot(context=self.context, id=i)
|
||||
for i in [3, 4, 5]]
|
||||
cgsnapshots = objects.CGSnapshotList(context=self.context,
|
||||
objects=cgsnapshots_objs)
|
||||
mock_cgsnap_get_all_by_group.return_value = cgsnapshots
|
||||
self.assertEqual(cgsnapshots, consistencygroup.cgsnapshots)
|
||||
mock_cgsnap_get_all_by_group.assert_called_once_with(
|
||||
self.context, consistencygroup.id)
|
||||
|
||||
# Test volumes lazy-loaded field
|
||||
volume_objs = [objects.Volume(context=self.context, id=i)
|
||||
for i in [3, 4, 5]]
|
||||
volumes = objects.VolumeList(context=self.context, objects=volume_objs)
|
||||
mock_vol_get_all_by_group.return_value = volumes
|
||||
self.assertEqual(volumes, consistencygroup.volumes)
|
||||
mock_vol_get_all_by_group.assert_called_once_with(self.context,
|
||||
consistencygroup.id)
|
||||
|
||||
@mock.patch('cinder.db.consistencygroup_destroy')
|
||||
def test_destroy(self, consistencygroup_destroy):
|
||||
consistencygroup = objects.ConsistencyGroup(context=self.context,
|
||||
|
||||
@@ -26,7 +26,7 @@ object_data = {
|
||||
'BackupList': '1.0-24591dabe26d920ce0756fe64cd5f3aa',
|
||||
'CGSnapshot': '1.0-190da2a2aa9457edc771d888f7d225c4',
|
||||
'CGSnapshotList': '1.0-e8c3f4078cd0ee23487b34d173eec776',
|
||||
'ConsistencyGroup': '1.0-b9bad093daee0b259edddb3993c60c31',
|
||||
'ConsistencyGroup': '1.1-8d8b867a67c1bd6e9f840bcf5e375dbb',
|
||||
'ConsistencyGroupList': '1.0-09d0aad5491e762ecfdf66bef02ceb8d',
|
||||
'Service': '1.0-64baeb4911dbab1153064dd1c87edb9f',
|
||||
'ServiceList': '1.0-d242d3384b68e5a5a534e090ff1d5161',
|
||||
|
||||
Reference in New Issue
Block a user