]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
rbd.py: add new error for deleting an image with snapshots
authorJosh Durgin <josh.durgin@dreamhost.com>
Wed, 2 May 2012 15:03:37 +0000 (08:03 -0700)
committerSage Weil <sage@newdream.net>
Wed, 2 May 2012 20:59:15 +0000 (13:59 -0700)
Forgot to update the python bindings in
88dda3be5aed38c8f587af9b27cb54a0fcca7530

Signed-off-by: Josh Durgin <josh.durgin@dreamhost.com>
src/pybind/rbd.py
src/test/pybind/test_rbd.py

index d9c554b575be7f3b524cfa5c2413ff4ef9a52fbe..7cb5d228dba15d17e67955fa59209cb25f1f3d65 100644 (file)
@@ -56,6 +56,9 @@ class ReadOnlyImage(Error):
 class ImageBusy(Error):
     pass
 
+class ImageHasSnapshots(Error):
+    pass
+
 def make_ex(ret, msg):
     """
     Translate a librbd return code into an exception.
@@ -67,14 +70,15 @@ def make_ex(ret, msg):
     :returns: a subclass of :class:`Error`
     """
     errors = {
-        errno.EPERM  : PermissionError,
-        errno.ENOENT : ImageNotFound,
-        errno.EIO    : IOError,
-        errno.ENOSPC : NoSpace,
-        errno.EEXIST : ImageExists,
-        errno.EINVAL : InvalidArgument,
-        errno.EROFS  : ReadOnlyImage,
-        errno.EBUSY  : ImageBusy,
+        errno.EPERM     : PermissionError,
+        errno.ENOENT    : ImageNotFound,
+        errno.EIO       : IOError,
+        errno.ENOSPC    : NoSpace,
+        errno.EEXIST    : ImageExists,
+        errno.EINVAL    : InvalidArgument,
+        errno.EROFS     : ReadOnlyImage,
+        errno.EBUSY     : ImageBusy,
+        errno.ENOTEMPTY : ImageHasSnapshots,
         }
     ret = abs(ret)
     if ret in errors:
@@ -163,13 +167,16 @@ class RBD(object):
         not return until every object that comprises the image has
         been deleted. Note that all snapshots must be deleted before
         the image can be removed. If there are snapshots left,
+        :class:`ImageHasSnapshots` is raised. If the image is still
+        open, or the watch from a crashed client has not expired,
         :class:`ImageBusy` is raised.
 
         :param ioctx: determines which RADOS pool the image is in
         :type ioctx: :class:`rados.Ioctx`
         :param name: the name of the image to remove
         :type name: str
-        :raises: :class:`ImageNotFound`, :class:`ImageBusy`
+        :raises: :class:`ImageNotFound`, :class:`ImageBusy`,
+                 :class:`ImageHasSnapshots`
         """
         if not isinstance(name, str):
             raise TypeError('name must be a string')
index 7edf8e97a26e3bc42f327f0ddfe4e19e380acd37..94176dff612652088075edc06593796674e2d801 100644 (file)
@@ -5,7 +5,7 @@ from nose import with_setup
 from nose.tools import eq_ as eq, assert_raises
 from rados import Rados
 from rbd import (RBD, Image, ImageNotFound, InvalidArgument, ImageExists,
-                 ImageBusy)
+                 ImageBusy, ImageHasSnapshots)
 
 
 rados = None
@@ -195,9 +195,12 @@ class TestImage(object):
 
     def test_remove_with_snap(self):
         self.image.create_snap('snap1')
-        assert_raises(ImageBusy, remove_image)
+        assert_raises(ImageHasSnapshots, remove_image)
         self.image.remove_snap('snap1')
 
+    def test_remove_with_watcher(self):
+        assert_raises(ImageBusy, remove_image)
+
     def test_rollback_to_snap(self):
         self.image.write('\0' * 256, 0)
         self.image.create_snap('snap1')