import mox as mox_lib
+from cinder import context
+from cinder import db
from cinder import test
from cinder import units
from cinder.volume import configuration as conf
self.nms_mock.snapshot.destroy('cinder/volume1@snapshot1', '')
self.mox.ReplayAll()
self.drv.delete_snapshot(self.TEST_SNAPSHOT_REF)
+ self.mox.ResetAll()
+
+ # Check that exception not raised if snapshot does not exist
+ mock = self.nms_mock.snapshot.destroy('cinder/volume1@snapshot1', '')
+ mock.AndRaise(nexenta.NexentaException(
+ 'Snapshot cinder/volume1@snapshot1 does not exist'))
+ self.mox.ReplayAll()
+ self.drv.delete_snapshot(self.TEST_SNAPSHOT_REF)
_CREATE_EXPORT_METHODS = [
('stmf', 'list_targets', tuple(), [], False, ),
'root': 'nobody'
}
+ def _create_volume_db_entry(self):
+ vol = {
+ 'id': '1',
+ 'size': 1,
+ 'status': 'available',
+ 'provider_location': self.TEST_EXPORT1
+ }
+ return db.volume_create(self.ctxt, vol)['id']
+
def setUp(self):
super(TestNexentaNfsDriver, self).setUp()
+ self.ctxt = context.get_admin_context()
self.configuration = mox_lib.MockObject(conf.Configuration)
self.configuration.nexenta_shares_config = None
self.configuration.nexenta_mount_point_base = '$state_path/mnt'
self.configuration.nfs_mount_options = None
self.configuration.nexenta_nms_cache_volroot = False
self.nms_mock = self.mox.CreateMockAnything()
- for mod in ('appliance', 'folder', 'server', 'volume', 'netstorsvc'):
+ for mod in ('appliance', 'folder', 'server', 'volume', 'netstorsvc',
+ 'snapshot'):
setattr(self.nms_mock, mod, self.mox.CreateMockAnything())
self.nms_mock.__hash__ = lambda *_, **__: 1
self.stubs.Set(jsonrpc, 'NexentaJSONProxy',
self.assertEqual(volume_name, 'stack')
self.assertEqual(folder_name, 'share')
+
+ def test_delete_snapshot(self):
+ self.drv.share2nms = {self.TEST_EXPORT1: self.nms_mock}
+ self._create_volume_db_entry()
+
+ self.nms_mock.server.get_prop('volroot').AndReturn('/volumes')
+ self.nms_mock.snapshot.destroy('stack/share/volume-1@snapshot1', '')
+ self.mox.ReplayAll()
+ self.drv.delete_snapshot({'volume_id': '1', 'name': 'snapshot1'})
+ self.mox.ResetAll()
+
+ # Check that exception not raised if snapshot does not exist on
+ # NexentaStor appliance.
+ self.nms_mock.server.get_prop('volroot').AndReturn('/volumes')
+ mock = self.nms_mock.snapshot.destroy('stack/share/volume-1@snapshot1',
+ '')
+ mock.AndRaise(nexenta.NexentaException("Snapshot does not exist"))
+ self.mox.ReplayAll()
+ self.drv.delete_snapshot({'volume_id': '1', 'name': 'snapshot1'})
+ self.mox.ResetAll()
+
+ def test_delete_volume(self):
+ self.drv.share2nms = {self.TEST_EXPORT1: self.nms_mock}
+ self._create_volume_db_entry()
+
+ self.drv._ensure_share_mounted = lambda *_, **__: 0
+ self.drv._execute = lambda *_, **__: 0
+
+ self.nms_mock.server.get_prop('volroot').AndReturn('/volumes')
+ self.nms_mock.folder.destroy('stack/share/volume-1', '')
+ self.mox.ReplayAll()
+ self.drv.delete_volume({
+ 'id': '1',
+ 'name': 'volume-1',
+ 'provider_location': self.TEST_EXPORT1
+ })
+ self.mox.ResetAll()
+
+ # Check that exception not raised if folder does not exist on
+ # NexentaStor appliance.
+ self.nms_mock.server.get_prop('volroot').AndReturn('/volumes')
+ mock = self.nms_mock.folder.destroy('stack/share/volume-1', '')
+ mock.AndRaise(nexenta.NexentaException("Folder does not exist"))
+ self.mox.ReplayAll()
+ self.drv.delete_volume({
+ 'id': '1',
+ 'name': 'volume-1',
+ 'provider_location': self.TEST_EXPORT1
+ })
+ self.mox.ResetAll()
# License for the specific language governing permissions and limitations
# under the License.
"""
-:mod:`nexenta.volume` -- Driver to store volumes on Nexenta Appliance
+:mod:`nexenta.iscsi` -- Driver to store volumes on Nexenta Appliance
=====================================================================
.. automodule:: nexenta.volume
1.0.1 - Fixed bug #1236626: catch "does not exist" exception of
lu_exists.
1.1.0 - Changed class name to NexentaISCSIDriver.
+ 1.1.1 - Ignore "does not exist" exception of nms.snapshot.destroy.
"""
- VERSION = '1.1.0'
+ VERSION = '1.1.1'
def __init__(self, *args, **kwargs):
super(NexentaISCSIDriver, self).__init__(*args, **kwargs)
except nexenta.NexentaException as exc:
if "does not exist" in exc.args[0]:
LOG.info(_('Volume %s does not exist, it seems it was already '
- 'deleted'), volume['name'])
+ 'deleted.'), volume['name'])
return
if "zvol has children" in exc.args[0]:
raise exception.VolumeIsBusy(volume_name=volume['name'])
:param snapshot: snapshot reference
"""
+ volume_name = self._get_zvol_name(snapshot['volume_name'])
+ snapshot_name = '%s@%s' % (volume_name, snapshot['name'])
try:
- self.nms.snapshot.destroy(
- '%s@%s' % (self._get_zvol_name(snapshot['volume_name']),
- snapshot['name']),
- '')
+ self.nms.snapshot.destroy(snapshot_name, '')
except nexenta.NexentaException as exc:
+ if "does not exist" in exc.args[0]:
+ LOG.info(_('Snapshot %s does not exist, it seems it was '
+ 'already deleted.'), snapshot_name)
+ return
if "snapshot has dependent clones" in exc.args[0]:
raise exception.SnapshotIsBusy(snapshot_name=snapshot['name'])
- else:
- raise
+ raise
def local_path(self, volume):
"""Return local path to existing local volume.
# License for the specific language governing permissions and limitations
# under the License.
"""
-:mod:`nexenta.nfs` -- Driver to store volumes on Nexenta Appliance
-=====================================================================
+:mod:`nexenta.nfs` -- Driver to store volumes on NexentaStor Appliance.
+=======================================================================
.. automodule:: nexenta.nfs
.. moduleauthor:: Mikhail Khodos <hodosmb@gmail.com>
from oslo.config import cfg
from cinder import context
+from cinder import db
from cinder import exception
from cinder.openstack.common import log as logging
from cinder import units
from cinder.volume.drivers.nexenta import utils
from cinder.volume.drivers import nfs
-VERSION = '1.1.1'
+VERSION = '1.1.2'
LOG = logging.getLogger(__name__)
CONF = cfg.CONF
1.0.0 - Initial driver version.
1.1.0 - Auto sharing for enclosing folder.
1.1.1 - Added caching for NexentaStor appliance 'volroot' value.
+ 1.1.2 - Ignore "folder does not exist" error in delete_volume and
+ delete_snapshot method.
"""
VERSION = VERSION
nms = self.share2nms[nfs_share]
vol, parent_folder = self._get_share_datasets(nfs_share)
folder = '%s/%s/%s' % (vol, parent_folder, volume['name'])
- nms.folder.destroy(folder, '')
+ try:
+ nms.folder.destroy(folder, '')
+ except nexenta.NexentaException as exc:
+ if 'does not exist' in exc.args[0]:
+ LOG.info(_('Folder %s does not exist, it seems it was '
+ 'already deleted.'), folder)
+ return
+ raise
def create_snapshot(self, snapshot):
"""Creates a snapshot.
nms = self.share2nms[nfs_share]
vol, dataset = self._get_share_datasets(nfs_share)
folder = '%s/%s/%s' % (vol, dataset, volume['name'])
- nms.snapshot.destroy('%s@%s' % (folder, snapshot['name']), '')
+ try:
+ nms.snapshot.destroy('%s@%s' % (folder, snapshot['name']), '')
+ except nexenta.NexentaException as exc:
+ if 'does not exist' in exc.args[0]:
+ LOG.info(_('Snapshot %s does not exist, it seems it was '
+ 'already deleted.'), '%s@%s' % (folder, snapshot))
+ return
+ raise
def _create_sparsed_file(self, nms, path, size):
"""Creates file with 0 disk usage.
def _get_snapshot_volume(self, snapshot):
ctxt = context.get_admin_context()
- return self.db.volume_get(ctxt, snapshot['volume_id'])
+ return db.volume_get(ctxt, snapshot['volume_id'])
def _get_volroot(self, nms):
"""Returns volroot property value from NexentaStor appliance."""