Merge "Add CG capability to generic groups in GPFS driver"
This commit is contained in:
commit
4f5b231c60
@ -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.'
|
||||
|
@ -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."""
|
||||
|
@ -0,0 +1,3 @@
|
||||
---
|
||||
features:
|
||||
- Added consistent group capability to generic volume groups in GPFS driver.
|
Loading…
Reference in New Issue
Block a user