Add minimum qemu-img version check functions

Functions for retrieving the qemu-img version and validate it
against driver specific requirements are added to imageutils.

This way, duplicated code can be removed in a following patch
from volume drivers that require it.

Change-Id: Ic0808863bd95c7ee84751a27d7a4eabc613f8d58
This commit is contained in:
Lucian Petrut 2015-02-27 15:55:13 +02:00
parent 33b8853816
commit eece1f7e94
2 changed files with 75 additions and 1 deletions

View File

@ -27,6 +27,7 @@ we should look at maybe pushing this up to Oslo
import contextlib
import math
import os
import re
import tempfile
from oslo_concurrency import processutils
@ -36,7 +37,7 @@ from oslo_utils import timeutils
from oslo_utils import units
from cinder import exception
from cinder.i18n import _
from cinder.i18n import _, _LW
from cinder.openstack.common import fileutils
from cinder.openstack.common import imageutils
from cinder import utils
@ -63,6 +64,36 @@ def qemu_img_info(path, run_as_root=True):
return imageutils.QemuImgInfo(out)
def get_qemu_img_version():
info = utils.execute('qemu-img', '--help', check_exit_code=False)[0]
pattern = r"qemu-img version ([0-9\.]*)"
version = re.match(pattern, info)
if not version:
LOG.warning(_LW("qemu-img is not installed."))
return None
return _get_version_from_string(version.groups()[0])
def _get_version_from_string(version_string):
return [int(x) for x in version_string.split('.')]
def check_qemu_img_version(minimum_version):
qemu_version = get_qemu_img_version()
if qemu_version < _get_version_from_string(minimum_version):
if qemu_version:
current_version = '.'.join((str(element)
for element in qemu_version))
else:
current_version = None
_msg = _('qemu-img %(minimum_version)s or later is required by '
'this volume driver. Current qemu-img version: '
'%(current_version)s') % {'minimum_version': minimum_version,
'current_version': current_version}
raise exception.VolumeBackendAPIException(data=_msg)
def _convert_image(prefix, source, dest, out_format, run_as_root=True):
"""Convert image to other format."""

View File

@ -69,6 +69,49 @@ class TestQemuImgInfo(test.TestCase):
run_as_root=True)
self.assertEqual(mock_info.return_value, output)
@mock.patch('cinder.utils.execute')
def test_get_qemu_img_version(self, mock_exec):
mock_out = "qemu-img version 2.0.0"
mock_err = mock.sentinel.err
mock_exec.return_value = (mock_out, mock_err)
expected_version = [2, 0, 0]
version = image_utils.get_qemu_img_version()
mock_exec.assert_called_once_with('qemu-img', '--help',
check_exit_code=False)
self.assertEqual(expected_version, version)
@mock.patch.object(image_utils, 'get_qemu_img_version')
def test_validate_qemu_img_version(self, mock_get_qemu_img_version):
fake_current_version = [1, 8]
mock_get_qemu_img_version.return_value = fake_current_version
minimum_version = '1.8'
image_utils.check_qemu_img_version(minimum_version)
mock_get_qemu_img_version.assert_called_once_with()
@mock.patch.object(image_utils, 'get_qemu_img_version')
def _test_validate_unsupported_qemu_img_version(self,
mock_get_qemu_img_version,
current_version=None):
mock_get_qemu_img_version.return_value = current_version
minimum_version = '2.0'
self.assertRaises(exception.VolumeBackendAPIException,
image_utils.check_qemu_img_version,
minimum_version)
mock_get_qemu_img_version.assert_called_once_with()
def test_validate_qemu_img_version_not_installed(self):
self._test_validate_unsupported_qemu_img_version()
def test_validate_older_qemu_img_version(self):
self._test_validate_unsupported_qemu_img_version(
current_version=[1, 8])
class TestConvertImage(test.TestCase):
@mock.patch('cinder.image.image_utils.os.stat')