Switch to qemu-img functions from ironic-lib 6.0.0

Change-Id: I0010d8710db4f2859dabe8ccfa5bf478d4f039f6
This commit is contained in:
Dmitry Tantsur 2024-03-11 17:16:12 +01:00
parent 1e84214d38
commit 4b31cc1c48
No known key found for this signature in database
GPG Key ID: 315B2AF9FD216C60
4 changed files with 44 additions and 43 deletions

View File

@ -23,7 +23,7 @@ import os
import shutil import shutil
import time import time
from ironic_lib import disk_utils from ironic_lib import qemu_img
from oslo_concurrency import processutils from oslo_concurrency import processutils
from oslo_log import log as logging from oslo_log import log as logging
from oslo_utils import fileutils from oslo_utils import fileutils
@ -378,7 +378,7 @@ def fetch(context, image_href, path, force_raw=False):
def get_source_format(image_href, path): def get_source_format(image_href, path):
data = disk_utils.qemu_img_info(path) data = qemu_img.image_info(path)
fmt = data.file_format fmt = data.file_format
if fmt is None: if fmt is None:
@ -415,10 +415,10 @@ def image_to_raw(image_href, path, path_tmp):
LOG.debug("%(image)s was %(format)s, converting to raw", LOG.debug("%(image)s was %(format)s, converting to raw",
{'image': image_href, 'format': fmt}) {'image': image_href, 'format': fmt})
with fileutils.remove_path_on_error(staged): with fileutils.remove_path_on_error(staged):
disk_utils.convert_image(path_tmp, staged, 'raw') qemu_img.convert_image(path_tmp, staged, 'raw')
os.unlink(path_tmp) os.unlink(path_tmp)
data = disk_utils.qemu_img_info(staged) data = qemu_img.image_info(staged)
if data.file_format != "raw": if data.file_format != "raw":
raise exception.ImageConvertFailed( raise exception.ImageConvertFailed(
image_id=image_href, image_id=image_href,
@ -454,7 +454,7 @@ def converted_size(path, estimate=False):
the original image scaled by the configuration value the original image scaled by the configuration value
`raw_image_growth_factor`. `raw_image_growth_factor`.
""" """
data = disk_utils.qemu_img_info(path) data = qemu_img.image_info(path)
if not estimate: if not estimate:
return data.virtual_size return data.virtual_size
growth_factor = CONF.raw_image_growth_factor growth_factor = CONF.raw_image_growth_factor

View File

@ -21,7 +21,7 @@ import os
import shutil import shutil
from unittest import mock from unittest import mock
from ironic_lib import disk_utils from ironic_lib import qemu_img
from oslo_concurrency import processutils from oslo_concurrency import processutils
from oslo_config import cfg from oslo_config import cfg
@ -72,40 +72,40 @@ class IronicImagesTestCase(base.TestCase):
image_to_raw_mock.assert_called_once_with( image_to_raw_mock.assert_called_once_with(
'image_href', 'path', 'path.part') 'image_href', 'path', 'path.part')
@mock.patch.object(disk_utils, 'qemu_img_info', autospec=True) @mock.patch.object(qemu_img, 'image_info', autospec=True)
def test_image_to_raw_no_file_format(self, qemu_img_info_mock): def test_image_to_raw_no_file_format(self, image_info_mock):
info = self.FakeImgInfo() info = self.FakeImgInfo()
info.file_format = None info.file_format = None
qemu_img_info_mock.return_value = info image_info_mock.return_value = info
e = self.assertRaises(exception.ImageUnacceptable, images.image_to_raw, e = self.assertRaises(exception.ImageUnacceptable, images.image_to_raw,
'image_href', 'path', 'path_tmp') 'image_href', 'path', 'path_tmp')
qemu_img_info_mock.assert_called_once_with('path_tmp') image_info_mock.assert_called_once_with('path_tmp')
self.assertIn("'qemu-img info' parsing failed.", str(e)) self.assertIn("'qemu-img info' parsing failed.", str(e))
@mock.patch.object(disk_utils, 'qemu_img_info', autospec=True) @mock.patch.object(qemu_img, 'image_info', autospec=True)
def test_image_to_raw_backing_file_present(self, qemu_img_info_mock): def test_image_to_raw_backing_file_present(self, image_info_mock):
info = self.FakeImgInfo() info = self.FakeImgInfo()
info.file_format = 'raw' info.file_format = 'raw'
info.backing_file = 'backing_file' info.backing_file = 'backing_file'
qemu_img_info_mock.return_value = info image_info_mock.return_value = info
e = self.assertRaises(exception.ImageUnacceptable, images.image_to_raw, e = self.assertRaises(exception.ImageUnacceptable, images.image_to_raw,
'image_href', 'path', 'path_tmp') 'image_href', 'path', 'path_tmp')
qemu_img_info_mock.assert_called_once_with('path_tmp') image_info_mock.assert_called_once_with('path_tmp')
self.assertIn("fmt=raw backed by: backing_file", str(e)) self.assertIn("fmt=raw backed by: backing_file", str(e))
@mock.patch.object(os, 'rename', autospec=True) @mock.patch.object(os, 'rename', autospec=True)
@mock.patch.object(os, 'unlink', autospec=True) @mock.patch.object(os, 'unlink', autospec=True)
@mock.patch.object(disk_utils, 'convert_image', autospec=True) @mock.patch.object(qemu_img, 'convert_image', autospec=True)
@mock.patch.object(disk_utils, 'qemu_img_info', autospec=True) @mock.patch.object(qemu_img, 'image_info', autospec=True)
def test_image_to_raw(self, qemu_img_info_mock, convert_image_mock, def test_image_to_raw(self, image_info_mock, convert_image_mock,
unlink_mock, rename_mock): unlink_mock, rename_mock):
CONF.set_override('force_raw_images', True) CONF.set_override('force_raw_images', True)
info = self.FakeImgInfo() info = self.FakeImgInfo()
info.file_format = 'fmt' info.file_format = 'fmt'
info.backing_file = None info.backing_file = None
qemu_img_info_mock.return_value = info image_info_mock.return_value = info
def convert_side_effect(source, dest, out_format): def convert_side_effect(source, dest, out_format):
info.file_format = 'raw' info.file_format = 'raw'
@ -113,45 +113,45 @@ class IronicImagesTestCase(base.TestCase):
images.image_to_raw('image_href', 'path', 'path_tmp') images.image_to_raw('image_href', 'path', 'path_tmp')
qemu_img_info_mock.assert_has_calls([mock.call('path_tmp'), image_info_mock.assert_has_calls([mock.call('path_tmp'),
mock.call('path.converted')]) mock.call('path.converted')])
convert_image_mock.assert_called_once_with('path_tmp', convert_image_mock.assert_called_once_with('path_tmp',
'path.converted', 'raw') 'path.converted', 'raw')
unlink_mock.assert_called_once_with('path_tmp') unlink_mock.assert_called_once_with('path_tmp')
rename_mock.assert_called_once_with('path.converted', 'path') rename_mock.assert_called_once_with('path.converted', 'path')
@mock.patch.object(os, 'unlink', autospec=True) @mock.patch.object(os, 'unlink', autospec=True)
@mock.patch.object(disk_utils, 'convert_image', autospec=True) @mock.patch.object(qemu_img, 'convert_image', autospec=True)
@mock.patch.object(disk_utils, 'qemu_img_info', autospec=True) @mock.patch.object(qemu_img, 'image_info', autospec=True)
def test_image_to_raw_not_raw_after_conversion(self, qemu_img_info_mock, def test_image_to_raw_not_raw_after_conversion(self, image_info_mock,
convert_image_mock, convert_image_mock,
unlink_mock): unlink_mock):
CONF.set_override('force_raw_images', True) CONF.set_override('force_raw_images', True)
info = self.FakeImgInfo() info = self.FakeImgInfo()
info.file_format = 'fmt' info.file_format = 'fmt'
info.backing_file = None info.backing_file = None
qemu_img_info_mock.return_value = info image_info_mock.return_value = info
self.assertRaises(exception.ImageConvertFailed, images.image_to_raw, self.assertRaises(exception.ImageConvertFailed, images.image_to_raw,
'image_href', 'path', 'path_tmp') 'image_href', 'path', 'path_tmp')
qemu_img_info_mock.assert_has_calls([mock.call('path_tmp'), image_info_mock.assert_has_calls([mock.call('path_tmp'),
mock.call('path.converted')]) mock.call('path.converted')])
convert_image_mock.assert_called_once_with('path_tmp', convert_image_mock.assert_called_once_with('path_tmp',
'path.converted', 'raw') 'path.converted', 'raw')
unlink_mock.assert_called_once_with('path_tmp') unlink_mock.assert_called_once_with('path_tmp')
@mock.patch.object(os, 'rename', autospec=True) @mock.patch.object(os, 'rename', autospec=True)
@mock.patch.object(disk_utils, 'qemu_img_info', autospec=True) @mock.patch.object(qemu_img, 'image_info', autospec=True)
def test_image_to_raw_already_raw_format(self, qemu_img_info_mock, def test_image_to_raw_already_raw_format(self, image_info_mock,
rename_mock): rename_mock):
info = self.FakeImgInfo() info = self.FakeImgInfo()
info.file_format = 'raw' info.file_format = 'raw'
info.backing_file = None info.backing_file = None
qemu_img_info_mock.return_value = info image_info_mock.return_value = info
images.image_to_raw('image_href', 'path', 'path_tmp') images.image_to_raw('image_href', 'path', 'path_tmp')
qemu_img_info_mock.assert_called_once_with('path_tmp') image_info_mock.assert_called_once_with('path_tmp')
rename_mock.assert_called_once_with('path_tmp', 'path') rename_mock.assert_called_once_with('path_tmp', 'path')
@mock.patch.object(image_service, 'get_image_service', autospec=True) @mock.patch.object(image_service, 'get_image_service', autospec=True)
@ -175,36 +175,36 @@ class IronicImagesTestCase(base.TestCase):
show_mock.assert_called_once_with('context', 'image_href', show_mock.assert_called_once_with('context', 'image_href',
'image_service') 'image_service')
@mock.patch.object(disk_utils, 'qemu_img_info', autospec=True) @mock.patch.object(qemu_img, 'image_info', autospec=True)
def test_converted_size_estimate_default(self, qemu_img_info_mock): def test_converted_size_estimate_default(self, image_info_mock):
info = self.FakeImgInfo() info = self.FakeImgInfo()
info.disk_size = 2 info.disk_size = 2
info.virtual_size = 10 ** 10 info.virtual_size = 10 ** 10
qemu_img_info_mock.return_value = info image_info_mock.return_value = info
size = images.converted_size('path', estimate=True) size = images.converted_size('path', estimate=True)
qemu_img_info_mock.assert_called_once_with('path') image_info_mock.assert_called_once_with('path')
self.assertEqual(4, size) self.assertEqual(4, size)
@mock.patch.object(disk_utils, 'qemu_img_info', autospec=True) @mock.patch.object(qemu_img, 'image_info', autospec=True)
def test_converted_size_estimate_custom(self, qemu_img_info_mock): def test_converted_size_estimate_custom(self, image_info_mock):
CONF.set_override('raw_image_growth_factor', 3) CONF.set_override('raw_image_growth_factor', 3)
info = self.FakeImgInfo() info = self.FakeImgInfo()
info.disk_size = 2 info.disk_size = 2
info.virtual_size = 10 ** 10 info.virtual_size = 10 ** 10
qemu_img_info_mock.return_value = info image_info_mock.return_value = info
size = images.converted_size('path', estimate=True) size = images.converted_size('path', estimate=True)
qemu_img_info_mock.assert_called_once_with('path') image_info_mock.assert_called_once_with('path')
self.assertEqual(6, size) self.assertEqual(6, size)
@mock.patch.object(disk_utils, 'qemu_img_info', autospec=True) @mock.patch.object(qemu_img, 'image_info', autospec=True)
def test_converted_size_estimate_raw_smaller(self, qemu_img_info_mock): def test_converted_size_estimate_raw_smaller(self, image_info_mock):
CONF.set_override('raw_image_growth_factor', 3) CONF.set_override('raw_image_growth_factor', 3)
info = self.FakeImgInfo() info = self.FakeImgInfo()
info.disk_size = 2 info.disk_size = 2
info.virtual_size = 5 info.virtual_size = 5
qemu_img_info_mock.return_value = info image_info_mock.return_value = info
size = images.converted_size('path', estimate=True) size = images.converted_size('path', estimate=True)
qemu_img_info_mock.assert_called_once_with('path') image_info_mock.assert_called_once_with('path')
self.assertEqual(5, size) self.assertEqual(5, size)
@mock.patch.object(images, 'get_image_properties', autospec=True) @mock.patch.object(images, 'get_image_properties', autospec=True)

View File

@ -14,7 +14,7 @@ WebOb>=1.7.1 # MIT
python-cinderclient!=4.0.0,>=3.3.0 # Apache-2.0 python-cinderclient!=4.0.0,>=3.3.0 # Apache-2.0
python-glanceclient>=2.8.0 # Apache-2.0 python-glanceclient>=2.8.0 # Apache-2.0
keystoneauth1>=4.2.0 # Apache-2.0 keystoneauth1>=4.2.0 # Apache-2.0
ironic-lib>=5.5.0 # Apache-2.0 ironic-lib>=6.0.0 # Apache-2.0
stevedore>=1.29.0 # Apache-2.0 stevedore>=1.29.0 # Apache-2.0
oslo.concurrency>=4.2.0 # Apache-2.0 oslo.concurrency>=4.2.0 # Apache-2.0
oslo.config>=6.8.0 # Apache-2.0 oslo.config>=6.8.0 # Apache-2.0

View File

@ -9,6 +9,7 @@ namespace = ironic_lib.json_rpc
namespace = ironic_lib.mdns namespace = ironic_lib.mdns
namespace = ironic_lib.metrics namespace = ironic_lib.metrics
namespace = ironic_lib.metrics_statsd namespace = ironic_lib.metrics_statsd
namespace = ironic_lib.qemu_img
namespace = ironic_lib.utils namespace = ironic_lib.utils
namespace = oslo.db namespace = oslo.db
namespace = oslo.messaging namespace = oslo.messaging