Merge "Add CG capability to generic groups in GPFS driver"

This commit is contained in:
Jenkins 2017-06-15 18:07:39 +00:00 committed by Gerrit Code Review
commit 4f5b231c60
3 changed files with 387 additions and 74 deletions

View File

@ -1402,9 +1402,11 @@ class GPFSDriverTestCase(test.TestCase):
self.driver.copy_volume_to_image('', volume, '', '')
@mock.patch('cinder.utils.execute')
@mock.patch('cinder.volume.drivers.ibm.gpfs.GPFSDriver.'
'_get_volume_path')
@mock.patch('cinder.volume.drivers.ibm.gpfs.GPFSDriver.'
'_can_migrate_locally')
def test_migrate_volume_ok(self, mock_local, mock_exec):
def test_migrate_volume_ok(self, mock_local, volume_path, mock_exec):
volume = self._fake_volume()
host = {}
host = {'host': 'foo', 'capabilities': {}}
@ -1439,9 +1441,11 @@ class GPFSDriverTestCase(test.TestCase):
self.driver._migrate_volume(volume, host))
@mock.patch('cinder.utils.execute')
@mock.patch('cinder.volume.drivers.ibm.gpfs.GPFSDriver.'
'_get_volume_path')
@mock.patch('cinder.volume.drivers.ibm.gpfs.GPFSDriver.'
'_can_migrate_locally')
def test_migrate_volume_fail_mv(self, mock_local, mock_exec):
def test_migrate_volume_fail_mv(self, mock_local, mock_path, mock_exec):
volume = self._fake_volume()
host = {}
host = {'host': 'foo', 'capabilities': {}}
@ -1459,8 +1463,10 @@ class GPFSDriverTestCase(test.TestCase):
@mock.patch('cinder.volume.drivers.ibm.gpfs.GPFSDriver._migrate_volume')
@mock.patch('cinder.volume.drivers.ibm.gpfs.GPFSDriver.'
'_update_volume_storage_pool')
@mock.patch('cinder.volume.drivers.ibm.gpfs.GPFSDriver.local_path')
@mock.patch('cinder.volume.drivers.ibm.gpfs._different')
def test_retype_ok(self, mock_different, mock_strg_pool, mock_migrate_vol):
def test_retype_ok(self, mock_different, local_path,
mock_strg_pool, mock_migrate_vol):
ctxt = self.context
(volume, new_type, diff, host) = self._fake_retype_arguments()
self.driver.db = mock.Mock()
@ -1537,16 +1543,18 @@ class GPFSDriverTestCase(test.TestCase):
diff,
host))
@mock.patch('cinder.volume.drivers.ibm.gpfs.GPFSDriver.local_path')
@mock.patch('cinder.utils.execute')
def test_mkfs_ok(self, mock_exec):
def test_mkfs_ok(self, mock_exec, local_path):
volume = self._fake_volume()
self.driver._mkfs(volume, 'swap')
self.driver._mkfs(volume, 'swap', 'test')
self.driver._mkfs(volume, 'ext3', 'test')
self.driver._mkfs(volume, 'vfat', 'test')
@mock.patch('cinder.volume.drivers.ibm.gpfs.GPFSDriver.local_path')
@mock.patch('cinder.utils.execute')
def test_mkfs_fail_mk(self, mock_exec):
def test_mkfs_fail_mk(self, mock_exec, local_path):
volume = self._fake_volume()
mock_exec.side_effect = (
processutils.ProcessExecutionError(stdout='test', stderr='test'))
@ -1591,7 +1599,7 @@ class GPFSDriverTestCase(test.TestCase):
def test_create_consistencygroup(self, mock_exec):
ctxt = self.context
group = self._fake_group()
self.driver.create_consistencygroup(ctxt, group)
self.driver._create_consistencygroup(ctxt, group)
fsdev = self.driver._gpfs_device
cgname = "consisgroup-%s" % group['id']
cgpath = os.path.join(self.driver.configuration.gpfs_mount_point_base,
@ -1610,7 +1618,7 @@ class GPFSDriverTestCase(test.TestCase):
mock_exec.side_effect = (
processutils.ProcessExecutionError(stdout='test', stderr='test'))
self.assertRaises(exception.VolumeBackendAPIException,
self.driver.create_consistencygroup, ctxt, group)
self.driver._create_consistencygroup, ctxt, group)
@mock.patch('cinder.utils.execute')
def test_delete_consistencygroup(self, mock_exec):
@ -1625,7 +1633,7 @@ class GPFSDriverTestCase(test.TestCase):
self.driver.db.volume_get_all_by_group = mock.Mock()
self.driver.db.volume_get_all_by_group.return_value = volumes
self.driver.delete_consistencygroup(ctxt, group, [])
self.driver._delete_consistencygroup(ctxt, group, [])
fsdev = self.driver._gpfs_device
cgname = "consisgroup-%s" % group['id']
cmd = ['mmlsfileset', fsdev, cgname]
@ -1650,7 +1658,7 @@ class GPFSDriverTestCase(test.TestCase):
mock_exec.side_effect = (
processutils.ProcessExecutionError(exit_code=2))
self.driver.delete_consistencygroup(ctxt, group, [])
self.driver._delete_consistencygroup(ctxt, group, [])
fsdev = self.driver._gpfs_device
cgname = "consisgroup-%s" % group['id']
cmd = ['mmlsfileset', fsdev, cgname]
@ -1668,19 +1676,20 @@ class GPFSDriverTestCase(test.TestCase):
mock_exec.side_effect = (
processutils.ProcessExecutionError(stdout='test', stderr='test'))
self.assertRaises(exception.VolumeBackendAPIException,
self.driver.delete_consistencygroup, ctxt, group, [])
self.driver._delete_consistencygroup,
ctxt, group, [])
def test_update_consistencygroup(self):
ctxt = self.context
group = self._fake_group()
self.assertRaises(exception.GPFSDriverUnsupportedOperation,
self.driver.update_consistencygroup, ctxt, group)
self.driver._update_consistencygroup, ctxt, group)
def test_create_consisgroup_from_src(self):
ctxt = self.context
group = self._fake_group()
self.assertRaises(exception.GPFSDriverUnsupportedOperation,
self.driver.create_consistencygroup_from_src,
self.driver._create_consistencygroup_from_src,
ctxt, group, [])
@mock.patch('cinder.volume.drivers.ibm.gpfs.GPFSDriver.create_snapshot')
@ -1688,8 +1697,8 @@ class GPFSDriverTestCase(test.TestCase):
ctxt = self.context
cgsnap = self._fake_cgsnapshot()
snapshot1 = self._fake_snapshot()
model_update, snapshots = self.driver.create_cgsnapshot(ctxt, cgsnap,
[snapshot1])
model_update, snapshots = self.driver._create_cgsnapshot(ctxt, cgsnap,
[snapshot1])
self.driver.create_snapshot.assert_called_once_with(snapshot1)
self.assertEqual({'status': fields.ConsistencyGroupStatus.AVAILABLE},
model_update)
@ -1701,8 +1710,8 @@ class GPFSDriverTestCase(test.TestCase):
def test_create_cgsnapshot_empty(self, mock_create_snap):
ctxt = self.context
cgsnap = self._fake_cgsnapshot()
model_update, snapshots = self.driver.create_cgsnapshot(ctxt, cgsnap,
[])
model_update, snapshots = self.driver._create_cgsnapshot(ctxt, cgsnap,
[])
self.assertFalse(self.driver.create_snapshot.called)
self.assertEqual({'status': fields.ConsistencyGroupStatus.AVAILABLE},
model_update)
@ -1712,8 +1721,8 @@ class GPFSDriverTestCase(test.TestCase):
ctxt = self.context
cgsnap = self._fake_cgsnapshot()
snapshot1 = self._fake_snapshot()
model_update, snapshots = self.driver.delete_cgsnapshot(ctxt, cgsnap,
[snapshot1])
model_update, snapshots = self.driver._delete_cgsnapshot(ctxt, cgsnap,
[snapshot1])
self.driver.delete_snapshot.assert_called_once_with(snapshot1)
self.assertEqual({'status': fields.ConsistencyGroupStatus.DELETED},
model_update)
@ -1725,8 +1734,8 @@ class GPFSDriverTestCase(test.TestCase):
def test_delete_cgsnapshot_empty(self, mock_delete_snap):
ctxt = self.context
cgsnap = self._fake_cgsnapshot()
model_update, snapshots = self.driver.delete_cgsnapshot(ctxt, cgsnap,
[])
model_update, snapshots = self.driver._delete_cgsnapshot(ctxt, cgsnap,
[])
self.assertFalse(self.driver.delete_snapshot.called)
self.assertEqual({'status': fields.ConsistencyGroupStatus.DELETED},
model_update)
@ -1741,8 +1750,14 @@ class GPFSDriverTestCase(test.TestCase):
ret = self.driver.local_path(volume)
self.assertEqual(volume_path, ret)
def test_local_path_volume_in_cg(self):
@mock.patch('cinder.db.get_by_id')
@mock.patch('cinder.volume.utils.is_group_a_cg_snapshot_type')
def test_local_path_volume_in_cg(self, mock_group_cg_snapshot_type,
mock_group_obj):
mock_group_cg_snapshot_type.return_value = True
volume = self._fake_volume()
group = self._fake_group()
mock_group_obj.return_value = group
cgname = "consisgroup-%s" % volume['group_id']
volume_path = os.path.join(
self.driver.configuration.gpfs_mount_point_base,
@ -1806,7 +1821,11 @@ class GPFSDriverTestCase(test.TestCase):
group = {}
group['name'] = 'test_group'
group['id'] = fake.CONSISTENCY_GROUP_ID
return group
group['user_id'] = fake.USER_ID
group['group_type_id'] = fake.GROUP_TYPE_ID
group['project_id'] = fake.PROJECT_ID
return objects.Group(self.context, **group)
def _fake_cgsnapshot(self):
snapshot = self._fake_snapshot()
@ -1851,6 +1870,150 @@ class GPFSDriverTestCase(test.TestCase):
return (volume, new_type, diff, host)
@mock.patch('cinder.volume.utils.is_group_a_cg_snapshot_type')
def test_create_group(self, mock_cg_snapshot_type):
mock_cg_snapshot_type.return_value = False
ctxt = self.context
group = self._fake_group()
self.assertRaises(
NotImplementedError,
self.driver.create_group,
ctxt, group
)
@mock.patch('cinder.volume.drivers.ibm.gpfs.GPFSDriver.'
'_create_consistencygroup')
@mock.patch('cinder.volume.utils.is_group_a_cg_snapshot_type')
def test_create_group_cg(self, mock_cg_snapshot_type,
mock_consisgroup_create):
mock_cg_snapshot_type.return_value = True
ctxt = self.context
group = self._fake_group()
self.driver.create_group(ctxt, group)
mock_consisgroup_create.assert_called_once_with(ctxt, group)
@mock.patch('cinder.volume.utils.is_group_a_cg_snapshot_type')
def test_delete_group(self, mock_cg_snapshot_type):
mock_cg_snapshot_type.return_value = False
ctxt = self.context
group = self._fake_group()
volumes = []
self.assertRaises(
NotImplementedError,
self.driver.delete_group,
ctxt, group, volumes
)
@mock.patch('cinder.volume.drivers.ibm.gpfs.GPFSDriver.'
'_delete_consistencygroup')
@mock.patch('cinder.volume.utils.is_group_a_cg_snapshot_type')
def test_delete_group_cg(self, mock_cg_snapshot_type,
mock_consisgroup_delete):
mock_cg_snapshot_type.return_value = True
ctxt = self.context
group = self._fake_group()
volumes = []
self.driver.delete_group(ctxt, group, volumes)
mock_consisgroup_delete.assert_called_once_with(ctxt, group, volumes)
@mock.patch('cinder.volume.utils.is_group_a_cg_snapshot_type')
def test_update_group(self, mock_cg_snapshot_type):
mock_cg_snapshot_type.return_value = False
ctxt = self.context
group = self._fake_group()
self.assertRaises(
NotImplementedError,
self.driver.update_group,
ctxt, group
)
@mock.patch('cinder.volume.drivers.ibm.gpfs.GPFSDriver.'
'_update_consistencygroup')
@mock.patch('cinder.volume.utils.is_group_a_cg_snapshot_type')
def test_update_group_cg(self, mock_cg_snapshot_type,
mock_consisgroup_update):
mock_cg_snapshot_type.return_value = True
ctxt = self.context
group = self._fake_group()
self.driver.update_group(ctxt, group)
mock_consisgroup_update.assert_called_once_with(ctxt, group,
None, None)
@mock.patch('cinder.volume.utils.is_group_a_cg_snapshot_type')
def test_create_group_snapshot(self, mock_cg_snapshot_type):
mock_cg_snapshot_type.return_value = False
ctxt = self.context
group_snapshot = mock.MagicMock()
snapshots = [mock.Mock()]
self.assertRaises(
NotImplementedError,
self.driver.create_group_snapshot,
ctxt, group_snapshot, snapshots
)
@mock.patch('cinder.volume.drivers.ibm.gpfs.GPFSDriver.'
'_create_cgsnapshot')
@mock.patch('cinder.volume.utils.is_group_a_cg_snapshot_type')
def test_create_group_snapshot_cg(self, mock_cg_snapshot_type,
mock_cgsnapshot_create):
mock_cg_snapshot_type.return_value = True
ctxt = self.context
group_snapshot = mock.MagicMock()
snapshots = [mock.Mock()]
self.driver.create_group_snapshot(ctxt, group_snapshot, snapshots)
mock_cgsnapshot_create.assert_called_once_with(ctxt, group_snapshot,
snapshots)
@mock.patch('cinder.volume.utils.is_group_a_cg_snapshot_type')
def test_delete_group_snapshot(self, mock_cg_snapshot_type):
mock_cg_snapshot_type.return_value = False
ctxt = self.context
group_snapshot = mock.MagicMock()
snapshots = [mock.Mock()]
self.assertRaises(
NotImplementedError,
self.driver.delete_group_snapshot,
ctxt, group_snapshot, snapshots
)
@mock.patch('cinder.volume.drivers.ibm.gpfs.GPFSDriver.'
'_delete_cgsnapshot')
@mock.patch('cinder.volume.utils.is_group_a_cg_snapshot_type')
def test_delete_group_snapshot_cg(self, mock_cg_snapshot_type,
mock_cgsnapshot_delete):
mock_cg_snapshot_type.return_value = True
ctxt = self.context
group_snapshot = mock.MagicMock()
snapshots = [mock.Mock()]
self.driver.delete_group_snapshot(ctxt, group_snapshot, snapshots)
mock_cgsnapshot_delete.assert_called_once_with(ctxt, group_snapshot,
snapshots)
@mock.patch('cinder.volume.utils.is_group_a_cg_snapshot_type')
def test_create_group_from_src(self, mock_cg_snapshot_type):
mock_cg_snapshot_type.return_value = False
ctxt = self.context
group = self._fake_group()
volumes = []
self.assertRaises(
NotImplementedError,
self.driver.create_group_from_src,
ctxt, group, volumes
)
@mock.patch('cinder.volume.drivers.ibm.gpfs.GPFSDriver.'
'_create_consistencygroup_from_src')
@mock.patch('cinder.volume.utils.is_group_a_cg_snapshot_type')
def test_create_group_from_src_cg(self, mock_cg_snapshot_type,
mock_cg_clone_create):
mock_cg_snapshot_type.return_value = True
ctxt = self.context
group = self._fake_group()
volumes = []
self.driver.create_group_from_src(ctxt, group, volumes)
mock_cg_clone_create.assert_called_once_with(ctxt, group, volumes,
None, None, None, None)
class GPFSRemoteDriverTestCase(test.TestCase):
"""Unit tests for GPFSRemoteDriver class"""
@ -2004,11 +2167,24 @@ class GPFSNFSDriverTestCase(test.TestCase):
def _fake_volume(self):
volume = {}
volume['id'] = '123456'
volume['name'] = 'test'
volume['id'] = fake.VOLUME_ID
volume['display_name'] = 'test'
volume['metadata'] = {'key1': 'val1'}
volume['_name_id'] = None
volume['size'] = 1000
volume['group_id'] = 'cg-1234'
return volume
volume['group_id'] = fake.CONSISTENCY_GROUP_ID
return objects.Volume(self.context, **volume)
def _fake_group(self):
group = {}
group['name'] = 'test_group'
group['id'] = fake.CONSISTENCY_GROUP_ID
group['user_id'] = fake.USER_ID
group['group_type_id'] = fake.GROUP_TYPE_ID
group['project_id'] = fake.PROJECT_ID
return objects.Group(self.context, **group)
def _fake_snapshot(self):
snapshot = {}
@ -2056,26 +2232,50 @@ class GPFSNFSDriverTestCase(test.TestCase):
self.assertEqual('GPFSNFS', stats['volume_backend_name'])
self.assertEqual('file', stats['storage_protocol'])
def test_get_volume_path(self):
@mock.patch('cinder.db.get_by_id')
@mock.patch('cinder.volume.utils.is_group_a_cg_snapshot_type')
def test_get_volume_path(self, mock_group_cg_snapshot_type, mock_group):
mock_group_cg_snapshot_type.return_value = True
self.driver.configuration.gpfs_mount_point_base = (
self.TEST_GPFS_MNT_POINT_BASE)
volume = self._fake_volume()
self.assertEqual('/export/consisgroup-cg-1234/test',
group = self._fake_group()
mock_group.return_value = group
volume_path_in_cg = os.path.join(self.TEST_GPFS_MNT_POINT_BASE,
'consisgroup-' +
fake.CONSISTENCY_GROUP_ID,
'volume-' + fake.VOLUME_ID)
self.assertEqual(volume_path_in_cg,
self.driver._get_volume_path(volume))
volume['group_id'] = None
self.assertEqual('/export/test',
volume.group_id = None
volume_path = os.path.join(self.TEST_GPFS_MNT_POINT_BASE,
'volume-' + fake.VOLUME_ID)
self.assertEqual(volume_path,
self.driver._get_volume_path(volume))
@mock.patch('cinder.db.get_by_id')
@mock.patch('cinder.volume.utils.is_group_a_cg_snapshot_type')
@mock.patch('cinder.volume.drivers.ibm.gpfs.GPFSNFSDriver.'
'_get_mount_point_for_share')
def test_local_path(self, mock_mount_point):
mock_mount_point.return_value = self.TEST_MNT_POINT
def test_local_path(self, mock_mount_point,
mock_group_cg_snapshot_type,
mock_group):
mock_mount_point.return_value = self.TEST_MNT_POINT_BASE
mock_group_cg_snapshot_type.return_value = True
volume = self._fake_volume()
volume['provider_location'] = self.TEST_GPFS_MNT_POINT_BASE
self.assertEqual('/mnt/nfs/consisgroup-cg-1234/test',
group = self._fake_group()
mock_group.return_value = group
volume['provider_location'] = self.TEST_MNT_POINT_BASE
local_volume_path_in_cg = os.path.join(self.TEST_MNT_POINT_BASE,
'consisgroup-' +
fake.CONSISTENCY_GROUP_ID,
'volume-' + fake.VOLUME_ID)
self.assertEqual(local_volume_path_in_cg,
self.driver.local_path(volume))
volume['group_id'] = None
self.assertEqual('/mnt/nfs/test',
volume.group_id = None
local_volume_path = os.path.join(self.TEST_MNT_POINT_BASE,
'volume-' + fake.VOLUME_ID)
self.assertEqual(local_volume_path,
self.driver.local_path(volume))
@mock.patch('cinder.volume.drivers.ibm.gpfs.GPFSNFSDriver.'

View File

@ -39,6 +39,7 @@ from cinder.volume import driver
from cinder.volume.drivers import nfs
from cinder.volume.drivers import remotefs
from cinder.volume.drivers.san import san
from cinder.volume import utils as volume_utils
GPFS_CLONE_MIN_RELEASE = 1200
GPFS_ENC_MIN_RELEASE = 1404
@ -771,18 +772,20 @@ class GPFSDriver(driver.CloneableImageVD,
"""Return the local path for the specified volume."""
# Check if the volume is part of a consistency group and return
# the local_path accordingly.
if volume['group_id'] is not None:
cgname = "consisgroup-%s" % volume['group_id']
volume_path = os.path.join(
self.configuration.gpfs_mount_point_base,
cgname,
volume['name']
)
else:
volume_path = os.path.join(
self.configuration.gpfs_mount_point_base,
volume['name']
)
if volume.group_id is not None:
if volume_utils.is_group_a_cg_snapshot_type(volume.group):
cgname = "consisgroup-%s" % volume.group_id
volume_path = os.path.join(
self.configuration.gpfs_mount_point_base,
cgname,
volume.name
)
return volume_path
volume_path = os.path.join(
self.configuration.gpfs_mount_point_base,
volume.name
)
return volume_path
def _get_gpfs_encryption_status(self):
@ -858,6 +861,7 @@ class GPFSDriver(driver.CloneableImageVD,
'root_path': gpfs_base})
data['consistencygroup_support'] = 'True'
data['consistent_group_snapshot_enabled'] = True
if self._encryption_state.lower() == 'yes':
data['gpfs_encryption_rest'] = 'True'
@ -1120,7 +1124,7 @@ class GPFSDriver(driver.CloneableImageVD,
LOG.error(msg)
raise exception.VolumeBackendAPIException(data=msg)
def create_consistencygroup(self, context, group):
def _create_consistencygroup(self, context, group):
"""Create consistency group of GPFS volumes."""
cgname = "consisgroup-%s" % group['id']
fsdev = self._gpfs_device
@ -1156,10 +1160,10 @@ class GPFSDriver(driver.CloneableImageVD,
LOG.error(msg)
raise exception.VolumeBackendAPIException(data=msg)
model_update = {'status': fields.ConsistencyGroupStatus.AVAILABLE}
model_update = {'status': fields.GroupStatus.AVAILABLE}
return model_update
def delete_consistencygroup(self, context, group, volumes):
def _delete_consistencygroup(self, context, group, volumes):
"""Delete consistency group of GPFS volumes."""
cgname = "consisgroup-%s" % group['id']
fsdev = self._gpfs_device
@ -1208,9 +1212,9 @@ class GPFSDriver(driver.CloneableImageVD,
return None, None
def create_cgsnapshot(self, context, cgsnapshot, snapshots):
def _create_cgsnapshot(self, context, cgsnapshot, snapshots):
"""Create snapshot of a consistency group of GPFS volumes."""
model_update = {'status': fields.ConsistencyGroupStatus.AVAILABLE}
model_update = {'status': fields.GroupStatus.AVAILABLE}
snapshots_model_update = []
try:
@ -1218,7 +1222,7 @@ class GPFSDriver(driver.CloneableImageVD,
self.create_snapshot(snapshot)
except exception.VolumeBackendAPIException as err:
model_update['status'] = (
fields.ConsistencyGroupStatus.ERROR)
fields.GroupStatus.ERROR)
LOG.error("Failed to create the snapshot %(snap)s of "
"CGSnapshot. Exception: %(exception)s.",
{'snap': snapshot.name, 'exception': err})
@ -1230,9 +1234,9 @@ class GPFSDriver(driver.CloneableImageVD,
return model_update, snapshots_model_update
def delete_cgsnapshot(self, context, cgsnapshot, snapshots):
def _delete_cgsnapshot(self, context, cgsnapshot, snapshots):
"""Delete snapshot of a consistency group of GPFS volumes."""
model_update = {'status': fields.ConsistencyGroupStatus.DELETED}
model_update = {'status': fields.GroupStatus.DELETED}
snapshots_model_update = []
try:
@ -1240,7 +1244,7 @@ class GPFSDriver(driver.CloneableImageVD,
self.delete_snapshot(snapshot)
except exception.VolumeBackendAPIException as err:
model_update['status'] = (
fields.ConsistencyGroupStatus.ERROR_DELETING)
fields.GroupStatus.ERROR_DELETING)
LOG.error("Failed to delete the snapshot %(snap)s of "
"CGSnapshot. Exception: %(exception)s.",
{'snap': snapshot.name, 'exception': err})
@ -1252,20 +1256,127 @@ class GPFSDriver(driver.CloneableImageVD,
return model_update, snapshots_model_update
def update_consistencygroup(self, context, group,
add_volumes=None, remove_volumes=None):
def _update_consistencygroup(self, context, group,
add_volumes=None, remove_volumes=None):
msg = _('Updating a consistency group is not supported.')
LOG.error(msg)
raise exception.GPFSDriverUnsupportedOperation(msg=msg)
def create_consistencygroup_from_src(self, context, group, volumes,
cgsnapshot=None, snapshots=None,
source_cg=None, source_vols=None):
def _create_consistencygroup_from_src(self, context, group, volumes,
cgsnapshot=None, snapshots=None,
source_cg=None, source_vols=None):
msg = _('Creating a consistency group from any source consistency '
'group or consistency group snapshot is not supported.')
LOG.error(msg)
raise exception.GPFSDriverUnsupportedOperation(msg=msg)
def create_group(self, ctxt, group):
"""Creates a group.
:param ctxt: the context of the caller.
:param group: the Group object of the group to be created.
:returns: model_update
"""
if volume_utils.is_group_a_cg_snapshot_type(group):
return self._create_consistencygroup(ctxt, group)
# If it wasn't a consistency group request ignore it and we'll rely on
# the generic group implementation.
raise NotImplementedError()
def delete_group(self, ctxt, group, volumes):
"""Deletes a group.
:param ctxt: the context of the caller.
:param group: the Group object of the group to be deleted.
:param volumes: a list of Volume objects in the group.
:returns: model_update, volumes_model_update
"""
if volume_utils.is_group_a_cg_snapshot_type(group):
return self._delete_consistencygroup(ctxt, group, volumes)
# If it wasn't a consistency group request ignore it and we'll rely on
# the generic group implementation.
raise NotImplementedError()
def update_group(self, ctxt, group,
add_volumes=None, remove_volumes=None):
"""Updates a group.
:param ctxt: the context of the caller.
:param group: the Group object of the group to be updated.
:param add_volumes: a list of Volume objects to be added.
:param remove_volumes: a list of Volume objects to be removed.
:returns: model_update, add_volumes_update, remove_volumes_update
"""
if volume_utils.is_group_a_cg_snapshot_type(group):
return self._update_consistencygroup(ctxt,
group,
add_volumes,
remove_volumes)
# If it wasn't a consistency group request ignore it and we'll rely on
# the generic group implementation.
raise NotImplementedError()
def create_group_snapshot(self, ctxt, group_snapshot, snapshots):
"""Creates a group_snapshot.
:param ctxt: the context of the caller.
:param group_snapshot: the GroupSnapshot object to be created.
:param snapshots: a list of Snapshot objects in the group_snapshot.
:returns: model_update, snapshots_model_update
"""
if volume_utils.is_group_a_cg_snapshot_type(group_snapshot):
return self._create_cgsnapshot(ctxt, group_snapshot, snapshots)
# If it wasn't a consistency group request ignore it and we'll rely on
# the generic group implementation.
raise NotImplementedError()
def delete_group_snapshot(self, ctxt, group_snapshot, snapshots):
"""Deletes a group_snapshot.
:param ctxt: the context of the caller.
:param group_snapshot: the GroupSnapshot object to be deleted.
:param snapshots: a list of snapshot objects in the group_snapshot.
:returns: model_update, snapshots_model_update
"""
if volume_utils.is_group_a_cg_snapshot_type(group_snapshot):
return self._delete_cgsnapshot(ctxt, group_snapshot, snapshots)
# If it wasn't a consistency group request ignore it and we'll rely on
# the generic group implementation.
raise NotImplementedError()
def create_group_from_src(self, ctxt, group, volumes,
group_snapshot=None, snapshots=None,
source_group=None, source_vols=None):
"""Creates a group from source.
:param ctxt: the context of the caller.
:param group: the Group object to be created.
:param volumes: a list of Volume objects in the group.
:param group_snapshot: the GroupSnapshot object as source.
:param snapshots: a list of snapshot objects in group_snapshot.
:param source_group: the Group object as source.
:param source_vols: a list of volume objects in the source_group.
:returns: model_update, volumes_model_update
"""
if volume_utils.is_group_a_cg_snapshot_type(group):
return self._create_consistencygroup_from_src(ctxt,
group,
volumes,
group_snapshot,
snapshots,
source_group,
source_vols)
# If it wasn't a consistency group request ignore it and we'll rely on
# the generic group implementation.
raise NotImplementedError()
@interface.volumedriver
class GPFSRemoteDriver(GPFSDriver, san.SanDriver):
@ -1467,18 +1578,18 @@ class GPFSNFSDriver(GPFSDriver, nfs.NfsDriver, san.SanDriver):
'root_path': gpfs_base})
data['consistencygroup_support'] = 'True'
data['consistent_group_snapshot_enabled'] = True
self._stats = data
LOG.debug("Exit _update_volume_stats.")
def _get_volume_path(self, volume):
"""Returns remote GPFS path for the given volume."""
export_path = self.configuration.gpfs_mount_point_base
if volume['group_id'] is not None:
cgname = "consisgroup-%s" % volume['group_id']
volume_path = os.path.join(export_path, cgname, volume['name'])
else:
volume_path = os.path.join(export_path, volume['name'])
return volume_path
if volume.group_id is not None:
if volume_utils.is_group_a_cg_snapshot_type(volume.group):
cgname = "consisgroup-%s" % volume.group_id
return os.path.join(export_path, cgname, volume.name)
return os.path.join(export_path, volume.name)
def local_path(self, volume):
"""Returns the local path for the specified volume."""
@ -1487,12 +1598,11 @@ class GPFSNFSDriver(GPFSDriver, nfs.NfsDriver, san.SanDriver):
# Check if the volume is part of a consistency group and return
# the local_path accordingly.
if volume['group_id'] is not None:
cgname = "consisgroup-%s" % volume['group_id']
volume_path = os.path.join(base_local_path, cgname, volume['name'])
else:
volume_path = os.path.join(base_local_path, volume['name'])
return volume_path
if volume.group_id is not None:
if volume_utils.is_group_a_cg_snapshot_type(volume.group):
cgname = "consisgroup-%s" % volume.group_id
return os.path.join(base_local_path, cgname, volume.name)
return os.path.join(base_local_path, volume.name)
def _get_snapshot_path(self, snapshot):
"""Returns remote GPFS path for the given snapshot."""

View File

@ -0,0 +1,3 @@
---
features:
- Added consistent group capability to generic volume groups in GPFS driver.