Make RBD imagebackend flatten method idempotent
If glance and nova are both configured with RBD backend, but glance does not return location information from the API, nova will fail to clone the image from glance pool and will download it from the API. In this case, image will be already flat, and subsequent flatten call will fail. This commit makes flatten call idempotent, so that it ignores already flat images by catching ImageUnacceptable when requesting parent info from ceph. Closes-Bug: 1860990 Change-Id: Ia6c184c31a980e4728b7309b2afaec4d9f494ac3 (cherry picked from commit65825ebfbd
) (cherry picked from commit03d59e2893
) (cherry picked from commitdd3c17216c
)
This commit is contained in:
parent
fd50cfacd2
commit
5d44052fed
|
@ -1550,11 +1550,28 @@ class RbdTestCase(_ImageTestCase, test.NoDBTestCase):
|
|||
["server1:1899", "server2:1920"]),
|
||||
model)
|
||||
|
||||
@mock.patch.object(rbd_utils.RBDDriver, 'parent_info')
|
||||
@mock.patch.object(rbd_utils.RBDDriver, 'flatten')
|
||||
def test_flatten(self, mock_flatten):
|
||||
def test_flatten(self, mock_flatten, mock_parent_info):
|
||||
image = self.image_class(self.INSTANCE, self.NAME)
|
||||
image.flatten()
|
||||
mock_flatten.assert_called_once_with(image.rbd_name, pool=self.POOL)
|
||||
mock_parent_info.assert_called_once_with(
|
||||
image.rbd_name, pool=self.POOL)
|
||||
|
||||
@mock.patch.object(imagebackend, 'LOG')
|
||||
@mock.patch.object(rbd_utils.RBDDriver, 'parent_info')
|
||||
@mock.patch.object(rbd_utils.RBDDriver, 'flatten')
|
||||
def test_flatten_already_flat(
|
||||
self, mock_flatten, mock_parent_info, mock_log):
|
||||
mock_parent_info.side_effect = exception.ImageUnacceptable(
|
||||
image_id=1, reason='foo')
|
||||
image = self.image_class(self.INSTANCE, self.NAME)
|
||||
image.flatten()
|
||||
mock_log.debug.assert_called_once()
|
||||
mock_flatten.assert_not_called()
|
||||
mock_parent_info.assert_called_once_with(
|
||||
image.rbd_name, pool=self.POOL)
|
||||
|
||||
def test_import_file(self):
|
||||
image = self.image_class(self.INSTANCE, self.NAME)
|
||||
|
|
|
@ -970,7 +970,17 @@ class Rbd(Image):
|
|||
reason=reason)
|
||||
|
||||
def flatten(self):
|
||||
self.driver.flatten(self.rbd_name, pool=self.pool)
|
||||
# NOTE(vdrok): only flatten images if they are not already flattened,
|
||||
# meaning that parent info is present
|
||||
try:
|
||||
self.driver.parent_info(self.rbd_name, pool=self.pool)
|
||||
except exception.ImageUnacceptable:
|
||||
LOG.debug(
|
||||
"Image %(img)s from pool %(pool)s has no parent info, "
|
||||
"consider it already flat", {
|
||||
'img': self.rbd_name, 'pool': self.pool})
|
||||
else:
|
||||
self.driver.flatten(self.rbd_name, pool=self.pool)
|
||||
|
||||
def get_model(self, connection):
|
||||
secret = None
|
||||
|
|
Loading…
Reference in New Issue