Use the json format output of qemu-img info

Support for the human format by oslo_utils.imageutils.QemuImgInfo was
deprecated since oslo.utils 4.9.1 [1]. This change replaces the human
format with the json format which will be used by default.

[1] 73eb0673f627aad382e08a816191b637af436465

Backport note: The json format is preferable because it allows access
to format specific details (since oslo.utils 4.1.0).  These details
are not present when the default 'human' format is used.  See change
I133da07a5a9628b8a9 for details.

Closes-Bug: #1940540
Change-Id: Ia0353204abf849467106ee08982d1271de23101a
(cherry picked from commit c0d2e7ebd8)
(cherry picked from commit 11b0f97a01)
(cherry picked from commit 4cef5c0c42)
(cherry picked from commit 9810c05e74)
(cherry picked from commit 60a5de1f6d)
(cherry picked from commit 6a1260ea80)
Conflicts:
  cinder/tests/unit/volume/drivers/test_nfs.py
  - patch changed QEMU_IMG_INFO_OUT5 test data which isn't present
    in ussuri
  cinder/volume/flows/manager/create_volume.py
  - parent patch of 6a1260ea8 imported netutils, but that's not used
    in this file in ussuri
(cherry picked from commit 6df27994d9)
This commit is contained in:
Takashi Kajinami 2021-07-06 21:48:44 +09:00 committed by Brian Rosmaita
parent 14c2db209b
commit 9f9194d804
5 changed files with 134 additions and 117 deletions

View File

@ -108,7 +108,7 @@ def from_qemu_img_disk_format(disk_format):
def qemu_img_info(path, run_as_root=True, force_share=False):
"""Return an object containing the parsed output from qemu-img info."""
cmd = ['env', 'LC_ALL=C', 'qemu-img', 'info']
cmd = ['env', 'LC_ALL=C', 'qemu-img', 'info', '--output=json']
if force_share:
if qemu_img_supports_force_share():
cmd.append('--force-share')
@ -122,7 +122,7 @@ def qemu_img_info(path, run_as_root=True, force_share=False):
cmd = cmd[2:]
out, _err = utils.execute(*cmd, run_as_root=run_as_root,
prlimit=QEMU_IMG_LIMITS)
info = imageutils.QemuImgInfo(out)
info = imageutils.QemuImgInfo(out, format='json')
# From Cinder's point of view, any 'luks' formatted images
# should be treated as 'raw'.

View File

@ -41,7 +41,8 @@ class TestQemuImgInfo(test.TestCase):
output = image_utils.qemu_img_info(test_path)
mock_exec.assert_called_once_with('env', 'LC_ALL=C', 'qemu-img',
'info', test_path, run_as_root=True,
'info', '--output=json', test_path,
run_as_root=True,
prlimit=image_utils.QEMU_IMG_LIMITS)
self.assertEqual(mock_info.return_value, output)
@ -58,7 +59,8 @@ class TestQemuImgInfo(test.TestCase):
force_share=False,
run_as_root=False)
mock_exec.assert_called_once_with('env', 'LC_ALL=C', 'qemu-img',
'info', test_path, run_as_root=False,
'info', '--output=json', test_path,
run_as_root=False,
prlimit=image_utils.QEMU_IMG_LIMITS)
self.assertEqual(mock_info.return_value, output)
@ -73,8 +75,8 @@ class TestQemuImgInfo(test.TestCase):
mock_os.name = 'nt'
output = image_utils.qemu_img_info(test_path)
mock_exec.assert_called_once_with('qemu-img', 'info', test_path,
run_as_root=True,
mock_exec.assert_called_once_with('qemu-img', 'info', '--output=json',
test_path, run_as_root=True,
prlimit=image_utils.QEMU_IMG_LIMITS)
self.assertEqual(mock_info.return_value, output)

View File

@ -330,51 +330,52 @@ NFS_CONFIG4 = {'max_over_subscription_ratio': 20.0,
'nas_secure_file_permissions': 'false',
'nas_secure_file_operations': 'true'}
QEMU_IMG_INFO_OUT1 = """image: %(volid)s
file format: raw
virtual size: %(size_gb)sG (%(size_b)s bytes)
disk size: 173K
"""
QEMU_IMG_INFO_OUT1 = """{
"filename": "%(volid)s",
"format": "raw",
"virtual-size": %(size_b)s,
"actual-size": 173000
}"""
QEMU_IMG_INFO_OUT2 = """image: %(volid)s
file format: qcow2
virtual size: %(size_gb)sG (%(size_b)s bytes)
disk size: 196K
cluster_size: 65536
Format specific information:
compat: 1.1
lazy refcounts: false
refcount bits: 16
corrupt: false
"""
QEMU_IMG_INFO_OUT2 = """{
"filename": "%(volid)s",
"format": "qcow2",
"virtual-size": %(size_b)s,
"actual-size": 196000,
"cluster-size": 65536,
"format-specific": {
"compat": "1.1",
"lazy-refcounts": false,
"refcount-bits": 16,
"corrupt": false
}
}"""
QEMU_IMG_INFO_OUT3 = """image: volume-%(volid)s.%(snapid)s
file format: qcow2
virtual size: %(size_gb)sG (%(size_b)s bytes)
disk size: 196K
cluster_size: 65536
backing file: volume-%(volid)s
backing file format: qcow2
Format specific information:
compat: 1.1
lazy refcounts: false
refcount bits: 16
corrupt: false
"""
QEMU_IMG_INFO_OUT3 = """{
"filename": "volume-%(volid)s.%(snapid)s",
"format": "qcow2",
"virtual-size": %(size_b)s,
"actual-size": 196000,
"cluster-size": 65536,
"backing-filename": "volume-%(volid)s",
"backing-filename-format": "qcow2",
"format-specific": {
"compat": "1.1",
"lazy-refcounts": false,
"refcount-bits": 16,
"corrupt": false
}
}"""
QEMU_IMG_INFO_OUT4 = """image: volume-%(volid)s.%(snapid)s
file format: raw
virtual size: %(size_gb)sG (%(size_b)s bytes)
disk size: 196K
cluster_size: 65536
backing file: volume-%(volid)s
backing file format: raw
Format specific information:
compat: 1.1
lazy refcounts: false
refcount bits: 16
corrupt: false
"""
QEMU_IMG_INFO_OUT4 = """{
"filename": "volume-%(volid)s.%(snapid)s",
"format": "raw",
"virtual-size": %(size_b)s,
"actual-size": 196000,
"cluster-size": 65536,
"backing-filename": "volume-%(volid)s",
"backing-filename-format": "raw"
}"""
@ddt.ddt
@ -1191,7 +1192,7 @@ class NfsDriverTestCase(test.TestCase):
'size_gb': src_volume.size,
'size_b': src_volume.size * units.Gi}
img_info = imageutils.QemuImgInfo(img_out)
img_info = imageutils.QemuImgInfo(img_out, format='json')
mock_img_info = self.mock_object(image_utils, 'qemu_img_info')
mock_img_info.return_value = img_info
mock_convert_image = self.mock_object(image_utils, 'convert_image')
@ -1262,7 +1263,7 @@ class NfsDriverTestCase(test.TestCase):
'snapid': fake_snap.id,
'size_gb': src_volume.size,
'size_b': src_volume.size * units.Gi}
img_info = imageutils.QemuImgInfo(img_out)
img_info = imageutils.QemuImgInfo(img_out, format='json')
mock_img_info = self.mock_object(image_utils, 'qemu_img_info')
mock_img_info.return_value = img_info
@ -1328,7 +1329,8 @@ class NfsDriverTestCase(test.TestCase):
mock_img_utils = self.mock_object(image_utils, 'qemu_img_info')
img_out = qemu_img_info % {'volid': volume.id, 'size_gb': volume.size,
'size_b': volume.size * units.Gi}
mock_img_utils.return_value = imageutils.QemuImgInfo(img_out)
mock_img_utils.return_value = imageutils.QemuImgInfo(img_out,
format='json')
self.mock_object(drv, '_read_info_file',
return_value={'active': "volume-%s" % volume.id})
@ -1348,12 +1350,14 @@ class NfsDriverTestCase(test.TestCase):
drv = self._driver
volume = self._simple_volume()
qemu_img_output = """image: %s
file format: iso
virtual size: 1.0G (1073741824 bytes)
disk size: 173K
""" % volume['name']
mock_img_info.return_value = imageutils.QemuImgInfo(qemu_img_output)
qemu_img_output = """{
"filename": "%s",
"format": "iso",
"virtual-size": 1073741824,
"actual-size": 173000
}""" % volume['name']
mock_img_info.return_value = imageutils.QemuImgInfo(qemu_img_output,
format='json')
self.assertRaises(exception.InvalidVolume,
drv.initialize_connection,

View File

@ -936,13 +936,14 @@ class QuobyteDriverTestCase(test.TestCase):
self.TEST_QUOBYTE_VOLUME),
self.VOLUME_UUID)
qemu_img_info_output = """image: volume-%s
file format: qcow2
virtual size: 1.0G (1073741824 bytes)
disk size: 473K
""" % self.VOLUME_UUID
qemu_img_info_output = """{
"filename": "volume-%s",
"format": "qcow2",
"virtual-size": 1073741824,
"actual-size": 473000
}""" % self.VOLUME_UUID
img_info = imageutils.QemuImgInfo(qemu_img_info_output)
img_info = imageutils.QemuImgInfo(qemu_img_info_output, format='json')
image_utils.qemu_img_info = mock.Mock(return_value=img_info)
image_utils.resize_image = mock.Mock()
@ -975,13 +976,14 @@ class QuobyteDriverTestCase(test.TestCase):
size = dest_volume['size']
qemu_img_output = """image: %s
file format: raw
virtual size: 1.0G (1073741824 bytes)
disk size: 173K
backing file: %s
""" % (snap_file, src_volume['name'])
img_info = imageutils.QemuImgInfo(qemu_img_output)
qemu_img_output = """{
"filename": "%s",
"format": "raw",
"virtual-size": 1073741824,
"actual-size": 173000,
"backing-filename": "%s"
}""" % (snap_file, src_volume['name'])
img_info = imageutils.QemuImgInfo(qemu_img_output, format='json')
# mocking and testing starts here
image_utils.convert_image = mock.Mock()
@ -1031,13 +1033,14 @@ class QuobyteDriverTestCase(test.TestCase):
size = dest_volume['size']
qemu_img_output = """image: %s
file format: raw
virtual size: 1.0G (1073741824 bytes)
disk size: 173K
backing file: %s
""" % (snap_file, src_volume['name'])
img_info = imageutils.QemuImgInfo(qemu_img_output)
qemu_img_output = """{
"filename": "%s",
"format": "raw",
"virtual-size": 1073741824,
"actual-size": 173000,
"backing-filename": "%s"
}""" % (snap_file, src_volume['name'])
img_info = imageutils.QemuImgInfo(qemu_img_output, format='json')
# mocking and testing starts here
image_utils.convert_image = mock.Mock()
@ -1092,13 +1095,14 @@ class QuobyteDriverTestCase(test.TestCase):
size = dest_volume['size']
qemu_img_output = """image: %s
file format: raw
virtual size: 1.0G (1073741824 bytes)
disk size: 173K
backing file: %s
""" % (snap_file, src_volume['name'])
img_info = imageutils.QemuImgInfo(qemu_img_output)
qemu_img_output = """{
"filename": "%s",
"format": "raw",
"virtual-size": 1073741824,
"actual-size": 173000,
"backing-filename": "%s"
}""" % (snap_file, src_volume['name'])
img_info = imageutils.QemuImgInfo(qemu_img_output, format='json')
# mocking and testing starts here
image_utils.convert_image = mock.Mock()
@ -1156,13 +1160,14 @@ class QuobyteDriverTestCase(test.TestCase):
size = dest_volume['size']
qemu_img_output = """image: %s
file format: raw
virtual size: 1.0G (1073741824 bytes)
disk size: 173K
backing file: %s
""" % (snap_file, src_volume['name'])
img_info = imageutils.QemuImgInfo(qemu_img_output)
qemu_img_output = """{
"filename": "%s",
"format": "raw",
"virtual-size": 1073741824,
"actual-size": 173000,
"backing-filename": "%s"
}""" % (snap_file, src_volume['name'])
img_info = imageutils.QemuImgInfo(qemu_img_output, format='json')
# mocking and testing starts here
image_utils.convert_image = mock.Mock()
@ -1247,12 +1252,13 @@ class QuobyteDriverTestCase(test.TestCase):
drv._get_hash_str(self.TEST_QUOBYTE_VOLUME))
vol_path = os.path.join(vol_dir, volume['name'])
qemu_img_output = """image: %s
file format: raw
virtual size: 1.0G (1073741824 bytes)
disk size: 173K
""" % volume['name']
img_info = imageutils.QemuImgInfo(qemu_img_output)
qemu_img_output = """{
"filename": "%s",
"format": "raw",
"virtual-size": 1073741824,
"actual-size": 173000
}""" % volume['name']
img_info = imageutils.QemuImgInfo(qemu_img_output, format='json')
drv.get_active_image_from_info = mock.Mock(return_value=volume['name'])
image_utils.qemu_img_info = mock.Mock(return_value=img_info)
@ -1293,12 +1299,13 @@ class QuobyteDriverTestCase(test.TestCase):
mock_create_temporary_file.return_value = self.TEST_TMP_FILE
qemu_img_output = """image: %s
file format: raw
virtual size: 1.0G (1073741824 bytes)
disk size: 173K
""" % volume['name']
img_info = imageutils.QemuImgInfo(qemu_img_output)
qemu_img_output = """{
"filename": "%s",
"format": "raw",
"virtual-size": 1073741824,
"actual-size": 173000
}""" % volume['name']
img_info = imageutils.QemuImgInfo(qemu_img_output, format='json')
mock_qemu_img_info.return_value = img_info
upload_path = volume_path
@ -1340,12 +1347,13 @@ class QuobyteDriverTestCase(test.TestCase):
mock_create_temporary_file.return_value = self.TEST_TMP_FILE
qemu_img_output = """image: %s
file format: qcow2
virtual size: 1.0G (1073741824 bytes)
disk size: 173K
""" % volume['name']
img_info = imageutils.QemuImgInfo(qemu_img_output)
qemu_img_output = """{
"filename": "%s",
"format": "qcow2",
"virtual-size": 1073741824,
"actual-size": 173000
}""" % volume['name']
img_info = imageutils.QemuImgInfo(qemu_img_output, format='json')
mock_qemu_img_info.return_value = img_info
upload_path = self.TEST_TMP_FILE
@ -1390,13 +1398,14 @@ class QuobyteDriverTestCase(test.TestCase):
mock_create_temporary_file.return_value = self.TEST_TMP_FILE
qemu_img_output = """image: volume-%s.%s
file format: qcow2
virtual size: 1.0G (1073741824 bytes)
disk size: 173K
backing file: %s
""" % (self.VOLUME_UUID, self.SNAP_UUID, volume_filename)
img_info = imageutils.QemuImgInfo(qemu_img_output)
qemu_img_output = """{
"filename": "volume-%s.%s",
"format": "qcow2",
"virtual-size": 1073741824,
"actual-size": 173000,
"backing-filename": "%s"
}""" % (self.VOLUME_UUID, self.SNAP_UUID, volume_filename)
img_info = imageutils.QemuImgInfo(qemu_img_output, format='json')
mock_qemu_img_info.return_value = img_info
upload_path = self.TEST_TMP_FILE

View File

@ -20,6 +20,7 @@ from oslo_config import cfg
from oslo_log import log as logging
from oslo_utils import excutils
from oslo_utils import fileutils
from oslo_utils import strutils
from oslo_utils import timeutils
import six
import taskflow.engines
@ -551,7 +552,8 @@ class CreateVolumeFromSpecTask(flow_utils.CinderTask):
volume,
encryption)
if image_info.encrypted == 'yes':
# see Bug #1942682 and Change I949f07582a708 for why we do this
if strutils.bool_from_string(image_info.encrypted):
key_str = source_pass + "\n" + new_pass + "\n"
del source_pass