]> review.fuel-infra Code Review - openstack-build/cinder-build.git/commitdiff
Add minimum qemu-img version check functions
authorLucian Petrut <lpetrut@cloudbasesolutions.com>
Fri, 27 Feb 2015 13:55:13 +0000 (15:55 +0200)
committerLucian Petrut <lpetrut@cloudbasesolutions.com>
Sat, 14 Mar 2015 23:32:55 +0000 (01:32 +0200)
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
cinder/tests/test_image_utils.py

index 902c444e2c90321b2271f5f799f8ae77f7c4ba92..601d66f53473ca23b1d1dbb18fb2590eb440fd40 100644 (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."""
 
index 9eb4a853ec36008c07623b51a70537373e15c6d0..ab4124383e8266cf9c340ccca2f42b2b08ac364d 100644 (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')