From eece1f7e94c2f53452a595b7b5cdaad03b98ce81 Mon Sep 17 00:00:00 2001 From: Lucian Petrut Date: Fri, 27 Feb 2015 15:55:13 +0200 Subject: [PATCH] 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 --- cinder/image/image_utils.py | 33 +++++++++++++++++++++++- cinder/tests/test_image_utils.py | 43 ++++++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+), 1 deletion(-) diff --git a/cinder/image/image_utils.py b/cinder/image/image_utils.py index 902c444e2..601d66f53 100644 --- a/cinder/image/image_utils.py +++ b/cinder/image/image_utils.py @@ -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.""" diff --git a/cinder/tests/test_image_utils.py b/cinder/tests/test_image_utils.py index 9eb4a853e..ab4124383 100644 --- a/cinder/tests/test_image_utils.py +++ b/cinder/tests/test_image_utils.py @@ -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') -- 2.45.2