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. NOTE(lyarwood): Conflict as I361af845d6a733618ecd056aa7df973191184ae9 is not present in stable/stein. Conflicts: nova/virt/libvirt/imagebackend.py Closes-Bug: 1860990 Change-Id: Ia6c184c31a980e4728b7309b2afaec4d9f494ac3 (cherry picked from commit65825ebfbd
) (cherry picked from commit03d59e2893
)
This commit is contained in:
parent
bf9d9e55e6
commit
dd3c17216c
|
@ -1565,11 +1565,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)
|
||||
|
|
|
@ -968,7 +968,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