Browse Source

Merge "Make RBD imagebackend flatten method idempotent"

changes/11/700811/11
Zuul 1 week ago
parent
commit
0d3aeb0287
2 changed files with 29 additions and 2 deletions
  1. +18
    -1
      nova/tests/unit/virt/libvirt/test_imagebackend.py
  2. +11
    -1
      nova/virt/libvirt/imagebackend.py

+ 18
- 1
nova/tests/unit/virt/libvirt/test_imagebackend.py View File

@@ -1582,11 +1582,28 @@ class RbdTestCase(_ImageTestCase, test.NoDBTestCase):
["server1:1899", "server2:1920", "[::1]:1930"]),
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)

+ 11
- 1
nova/virt/libvirt/imagebackend.py View File

@@ -980,7 +980,17 @@ class Rbd(Image):
reason=reason)

def flatten(self):
self.driver.flatten(self.rbd_name, pool=self.driver.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.driver.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.driver.pool})
else:
self.driver.flatten(self.rbd_name, pool=self.driver.pool)

def get_model(self, connection):
secret = None

Loading…
Cancel
Save