NEC Driver: Support revert to snapshot
Adding support to revert a volume to a snapshot in NEC driver. This patch implements revert_to_snapshot(). This patch also deletes unused classes(class UnpairWaitForBackup, class UnpairWaitForDDRBackup). Change-Id: I1bf5bd3856009e92921cbbd7f91734e070d5e86f
This commit is contained in:
parent
d229aa3cb1
commit
a6f4caabd3
@ -16,6 +16,7 @@
|
||||
|
||||
import ddt
|
||||
import mock
|
||||
import time
|
||||
|
||||
from cinder import context
|
||||
from cinder import exception
|
||||
@ -1439,3 +1440,62 @@ class ManageUnmanage_Snap_test(volume_helper.MStorageDSVDriver, test.TestCase):
|
||||
newsnap,
|
||||
snaps[0]['reference'])
|
||||
self.assertEqual(6, size_in_gb)
|
||||
|
||||
|
||||
class RevertToSnapshotTestCase(volume_helper.MStorageDSVDriver, test.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(RevertToSnapshotTestCase, self).setUp()
|
||||
self._set_config(conf.Configuration(None), 'dummy', 'dummy')
|
||||
self.do_setup(None)
|
||||
self.mock_object(self._cli, 'view_all', return_value=xml_out)
|
||||
|
||||
def test_revert_to_snapshot(self):
|
||||
vol = DummyVolume("1febb976-86d0-42ed-9bc0-4aa3e158f27d")
|
||||
snap = DummySnapshot("63410c76-2f12-4473-873d-74a63dfcd3e2")
|
||||
self.mock_object(time, 'sleep')
|
||||
self.mock_object(self._cli, '_execute',
|
||||
return_value=('success', 0, 0))
|
||||
self.mock_object(self._cli, 'query_BV_SV_status',
|
||||
return_value='snap/active')
|
||||
self.revert_to_snapshot(None, vol, snap)
|
||||
self._cli._execute.assert_called_once_with(
|
||||
'iSMsc_restore -bv yEUHrXa5AHMjOZZLb93eP -bvflg ld '
|
||||
'-sv 31HxzqBiAFTUxxOlcVn3EA -svflg ld -derivsv keep -nowait')
|
||||
|
||||
vol.id = constants.VOLUME_ID
|
||||
with self.assertRaisesRegex(exception.NotFound,
|
||||
'Logical Disk `LX:vD03hJCiHvGpvP4iSevKk` '
|
||||
'has unbound already.'):
|
||||
self.revert_to_snapshot(None, vol, snap)
|
||||
vol.id = '1febb976-86d0-42ed-9bc0-4aa3e158f27d'
|
||||
snap.id = constants.SNAPSHOT_ID
|
||||
with self.assertRaisesRegex(exception.NotFound,
|
||||
'Logical Disk `LX:18FkaTGqa43xSFL8aX4A2N` '
|
||||
'has unbound already.'):
|
||||
self.revert_to_snapshot(None, vol, snap)
|
||||
snap.id = '63410c76-2f12-4473-873d-74a63dfcd3e2'
|
||||
self.mock_object(self._cli, 'query_BV_SV_status',
|
||||
return_value='rst/exec')
|
||||
with self.assertRaisesRegex(exception.VolumeBackendAPIException,
|
||||
'The snapshot does not exist or is '
|
||||
'not in snap/active status. '
|
||||
'bvname=LX:yEUHrXa5AHMjOZZLb93eP, '
|
||||
'svname=LX:31HxzqBiAFTUxxOlcVn3EA, '
|
||||
'status=rst/exec'):
|
||||
self.revert_to_snapshot(None, vol, snap)
|
||||
|
||||
return_status = ['snap/active', 'rst/exec', 'snap/active']
|
||||
self.mock_object(self._cli, 'query_BV_SV_status',
|
||||
side_effect=return_status)
|
||||
self.revert_to_snapshot(None, vol, snap)
|
||||
|
||||
return_status = ['snap/active', 'rst/exec', 'snap/fault']
|
||||
self.mock_object(self._cli, 'query_BV_SV_status',
|
||||
side_effect=return_status)
|
||||
with self.assertRaisesRegex(exception.VolumeBackendAPIException,
|
||||
'Failed to restore from snapshot. '
|
||||
'bvname=LX:yEUHrXa5AHMjOZZLb93eP, '
|
||||
'svname=LX:31HxzqBiAFTUxxOlcVn3EA, '
|
||||
'status=snap/fault'):
|
||||
self.revert_to_snapshot(None, vol, snap)
|
||||
|
@ -584,6 +584,46 @@ class MStorageISMCLI(object):
|
||||
cmd = 'iSMcfg generationdel -bvname %s -count 1' % bvname
|
||||
self._execute(cmd)
|
||||
|
||||
def snapshot_restore(self, bvname, svname):
|
||||
"""Snapshot restore."""
|
||||
query_status = self.query_BV_SV_status(bvname[3:], svname[3:])
|
||||
if query_status == 'snap/active':
|
||||
cmd = ('iSMsc_restore -bv %(bv)s -bvflg ld -sv %(sv)s '
|
||||
'-svflg ld -derivsv keep -nowait'
|
||||
% {'bv': bvname[3:], 'sv': svname[3:]})
|
||||
self._execute(cmd)
|
||||
|
||||
retry_count = 0
|
||||
while True:
|
||||
query_status = self.query_BV_SV_status(bvname[3:], svname[3:])
|
||||
if query_status == 'rst/exec':
|
||||
# Restoration is in progress.
|
||||
sleep_time = get_sleep_time_for_clone(retry_count)
|
||||
LOG.debug('Sleep %d seconds Start', sleep_time)
|
||||
time.sleep(sleep_time)
|
||||
retry_count += 1
|
||||
elif query_status == 'snap/active':
|
||||
# Restoration was successful.
|
||||
break
|
||||
else:
|
||||
# Restoration failed.
|
||||
msg = (_('Failed to restore from snapshot. '
|
||||
'bvname=%(bvname)s, svname=%(svname)s, '
|
||||
'status=%(status)s') %
|
||||
{'bvname': bvname, 'svname': svname,
|
||||
'status': query_status})
|
||||
LOG.error(msg)
|
||||
raise exception.VolumeBackendAPIException(data=msg)
|
||||
else:
|
||||
msg = (_('The snapshot does not exist or is '
|
||||
'not in snap/active status. '
|
||||
'bvname=%(bvname)s, svname=%(svname)s, '
|
||||
'status=%(status)s') %
|
||||
{'bvname': bvname, 'svname': svname,
|
||||
'status': query_status})
|
||||
LOG.error(msg)
|
||||
raise exception.VolumeBackendAPIException(data=msg)
|
||||
|
||||
def query_BV_SV_status(self, bvname, svname):
|
||||
cmd = ('iSMsc_query -bv %(bv)s -bvflg ld -sv %(sv)s -svflg ld '
|
||||
'-summary | '
|
||||
@ -593,7 +633,12 @@ class MStorageISMCLI(object):
|
||||
% {'bv': bvname, 'sv': svname, 'line': svname})
|
||||
out, err, status = self._execute(cmd)
|
||||
|
||||
query_status = out[34:48].strip()
|
||||
delimiter = ') '
|
||||
start = out.find(delimiter)
|
||||
if start == -1:
|
||||
return None
|
||||
start += len(delimiter)
|
||||
query_status = out[start:].split(' ')[0]
|
||||
LOG.debug('snap/state:%s.', query_status)
|
||||
return query_status
|
||||
|
||||
@ -729,16 +774,6 @@ class UnpairWait(object):
|
||||
pass
|
||||
|
||||
|
||||
class UnpairWaitForBackup(UnpairWait):
|
||||
def __init__(self, volume_properties, cli):
|
||||
super(UnpairWaitForBackup, self).__init__(volume_properties, cli)
|
||||
|
||||
def _execute(self):
|
||||
LOG.debug('UnpairWaitForBackup start.')
|
||||
|
||||
self._wait(True)
|
||||
|
||||
|
||||
class UnpairWaitForRestore(UnpairWait):
|
||||
def __init__(self, volume_properties, cli):
|
||||
super(UnpairWaitForRestore, self).__init__(volume_properties, cli)
|
||||
@ -815,16 +850,6 @@ class UnpairWaitForMigrate(UnpairWait):
|
||||
self._volume_properties['rvname'])
|
||||
|
||||
|
||||
class UnpairWaitForDDRBackup(UnpairWaitForBackup):
|
||||
def __init__(self, volume_properties, cli):
|
||||
super(UnpairWaitForDDRBackup, self).__init__(volume_properties, cli)
|
||||
|
||||
def _execute(self):
|
||||
LOG.debug('UnpairWaitForDDRBackup start.')
|
||||
|
||||
self._wait(False)
|
||||
|
||||
|
||||
class UnpairWaitForDDRRestore(UnpairWaitForRestore):
|
||||
def __init__(self, volume_properties, cli):
|
||||
super(UnpairWaitForDDRRestore, self).__init__(volume_properties, cli)
|
||||
|
@ -50,6 +50,7 @@ class MStorageISCSIDriver(volume_helper.MStorageDSVDriver,
|
||||
1.11.1 - Add support pytyon 3.
|
||||
Add support for multi-attach.
|
||||
Add support of more than 4 iSCSI portals for a node.
|
||||
Add support to revert a volume to a snapshot.
|
||||
"""
|
||||
|
||||
VERSION = '1.11.1'
|
||||
@ -114,6 +115,7 @@ class MStorageFCDriver(volume_helper.MStorageDSVDriver,
|
||||
1.11.1 - Add support pytyon 3.
|
||||
Add support for multi-attach.
|
||||
Add support of more than 4 iSCSI portals for a node.
|
||||
Add support to revert a volume to a snapshot.
|
||||
"""
|
||||
|
||||
VERSION = '1.11.1'
|
||||
|
@ -1825,3 +1825,55 @@ class MStorageDSVDriver(MStorageDriver):
|
||||
'snap_id': snapshot.id,
|
||||
'snapvol_id': snapshot.volume_id,
|
||||
'specs': specs})
|
||||
|
||||
def revert_to_snapshot(self, context, volume, snapshot):
|
||||
"""called to perform revert volume from snapshot.
|
||||
|
||||
:param context: Our working context.
|
||||
:param volume: the volume to be reverted.
|
||||
:param snapshot: the snapshot data revert to volume.
|
||||
:return None
|
||||
"""
|
||||
msgparm = ('Volume ID = %(vol_id)s, '
|
||||
'Snapshot ID = %(snap_id)s, '
|
||||
'Snapshot Volume ID = %(snapvol_id)s'
|
||||
% {'vol_id': volume.id,
|
||||
'snap_id': snapshot.id,
|
||||
'snapvol_id': snapshot.volume_id})
|
||||
try:
|
||||
self._revert_to_snapshot(context, volume, snapshot)
|
||||
LOG.info('Reverted to Snapshot (%s)', msgparm)
|
||||
except exception.CinderException as e:
|
||||
with excutils.save_and_reraise_exception():
|
||||
LOG.warning('Failed to revert to Snapshot '
|
||||
'(%(msgparm)s) (%(exception)s)',
|
||||
{'msgparm': msgparm, 'exception': e})
|
||||
|
||||
def _revert_to_snapshot(self, context, volume, snapshot):
|
||||
LOG.debug('_revert_to_snapshot (Volume ID = %(vol_id)s, '
|
||||
'Snapshot ID = %(snap_id)s) Start.',
|
||||
{'vol_id': volume.id, 'snap_id': snapshot.id})
|
||||
xml = self._cli.view_all(self._properties['ismview_path'])
|
||||
pools, lds, ldsets, used_ldns, hostports, max_ld_count = (
|
||||
self.configs(xml))
|
||||
# get BV name.
|
||||
bvname = (
|
||||
self.get_ldname(volume.id,
|
||||
self._properties['ld_name_format']))
|
||||
if bvname not in lds:
|
||||
msg = _('Logical Disk `%s` has unbound already.') % bvname
|
||||
LOG.error(msg)
|
||||
raise exception.NotFound(msg)
|
||||
|
||||
# get SV name.
|
||||
svname = (
|
||||
self.get_ldname(snapshot.id,
|
||||
self._properties['ld_backupname_format']))
|
||||
if svname not in lds:
|
||||
msg = _('Logical Disk `%s` has unbound already.') % svname
|
||||
LOG.error(msg)
|
||||
raise exception.NotFound(msg)
|
||||
|
||||
self._cli.snapshot_restore(bvname, svname)
|
||||
|
||||
LOG.debug('_revert_to_snapshot(Volume ID = %s) End.', volume.id)
|
||||
|
@ -53,6 +53,8 @@ Supported operations
|
||||
- Manage and unmanage a volume.
|
||||
- Manage and unmanage a snapshot.
|
||||
- Attach a volume to multiple instances at once (multi-attach).
|
||||
- Revert a volume to a snapshot.
|
||||
|
||||
|
||||
Preparation
|
||||
~~~~~~~~~~~
|
||||
|
@ -852,7 +852,7 @@ driver.lenovo=missing
|
||||
driver.linbit_linstor=missing
|
||||
driver.lvm=complete
|
||||
driver.macrosan=missing
|
||||
driver.nec=missing
|
||||
driver.nec=complete
|
||||
driver.netapp_ontap=missing
|
||||
driver.netapp_solidfire=complete
|
||||
driver.nexenta=missing
|
||||
|
@ -0,0 +1,5 @@
|
||||
---
|
||||
features:
|
||||
- |
|
||||
NEC Driver: Added support to revert a volume to a snapshot.
|
||||
|
Loading…
Reference in New Issue
Block a user