]> review.fuel-infra Code Review - openstack-build/cinder-build.git/commitdiff
Nexenta drivers ignore "does not exist" exception
authorVictor Rodionov <vito.ordaz@gmail.com>
Wed, 16 Oct 2013 18:00:16 +0000 (11:00 -0700)
committerVictor Rodionov <vito.ordaz@gmail.com>
Tue, 22 Oct 2013 22:05:22 +0000 (15:05 -0700)
Ignore "does not exist" exception in NFS and iSCSI driver,
delete_volume and delete_snapshot methods.
This exceptions means that the volume or the snapshot not exists in the
backend, so we can avoid "delete" errors, when the resource was already
deleted.

Closes-Bug: 1240650
Change-Id: I3b2684097dcb95ba50a67c94a353dc3f17374777

cinder/tests/test_nexenta.py
cinder/volume/drivers/nexenta/iscsi.py
cinder/volume/drivers/nexenta/nfs.py

index 437b9a7892f1389e15b497ea38f7fa948f240083..b5318320c3bce258e8d3bd9443b746838072bfdb 100644 (file)
@@ -24,6 +24,8 @@ import urllib2
 
 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
@@ -150,6 +152,14 @@ class TestNexentaISCSIDriver(test.TestCase):
         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, ),
@@ -381,8 +391,18 @@ class TestNexentaNfsDriver(test.TestCase):
         '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'
@@ -392,7 +412,8 @@ class TestNexentaNfsDriver(test.TestCase):
         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',
@@ -594,3 +615,53 @@ class TestNexentaNfsDriver(test.TestCase):
 
         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()
index af4ec4ab13927f575436593f49476fb8519e9813..87a942d6ece87033c1137e9c5d268cb996a504c1 100644 (file)
@@ -15,7 +15,7 @@
 #    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
@@ -50,9 +50,10 @@ class NexentaISCSIDriver(driver.ISCSIDriver):  # pylint: disable=R0921
         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)
@@ -137,7 +138,7 @@ class NexentaISCSIDriver(driver.ISCSIDriver):  # pylint: disable=R0921
         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'])
@@ -208,16 +209,18 @@ class NexentaISCSIDriver(driver.ISCSIDriver):  # pylint: disable=R0921
 
         :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.
index cbe89d679ba8e2527debeb595c929f748543afe2..d163d49db9f3157dd776007549a8f57c8ddf9685 100644 (file)
@@ -15,8 +15,8 @@
 #    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>
@@ -29,6 +29,7 @@ import os
 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
@@ -38,7 +39,7 @@ from cinder.volume.drivers.nexenta import options
 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
@@ -52,6 +53,8 @@ class NexentaNfsDriver(nfs.NfsDriver):  # pylint: disable=R0921
         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
@@ -217,7 +220,14 @@ class NexentaNfsDriver(nfs.NfsDriver):  # pylint: disable=R0921
             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.
@@ -241,7 +251,14 @@ class NexentaNfsDriver(nfs.NfsDriver):  # pylint: disable=R0921
         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.
@@ -387,7 +404,7 @@ class NexentaNfsDriver(nfs.NfsDriver):  # pylint: disable=R0921
 
     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."""