from cinder import exception
from cinder.openstack.common import fileutils
from cinder.openstack.common import log as logging
+from cinder.openstack.common import processutils
from cinder.openstack.common import strutils
from cinder import utils
-
+from cinder.volume import utils as volume_utils
LOG = logging.getLogger(__name__)
os.path.exists(CONF.image_conversion_dir)):
os.makedirs(CONF.image_conversion_dir)
+ no_qemu_img = False
+ image_meta = image_service.show(context, image_id)
+
# NOTE(avishay): I'm not crazy about creating temp files which may be
# large and cause disk full errors which would confuse users.
# Unfortunately it seems that you can't pipe to 'qemu-img convert' because
# it seeks. Maybe we can think of something for a future version.
with temporary_file() as tmp:
+ # We may be on a system that doesn't have qemu-img installed. That
+ # is ok if we are working with a RAW image. This logic checks to see
+ # if qemu-img is installed. If not we make sure the image is RAW and
+ # throw an exception if not. Otherwise we stop before needing
+ # qemu-img. Systems with qemu-img will always progress through the
+ # whole function.
+ try:
+ # Use the empty tmp file to make sure qemu_img_info works.
+ qemu_img_info(tmp)
+ except processutils.ProcessExecutionError:
+ no_qemu_img = True
+ if image_meta:
+ if image_meta['disk_format'] != 'raw':
+ raise exception.ImageUnacceptable(
+ reason=_("qemu-img is not installed and image is of "
+ "type %s. Only RAW images can be used if "
+ "qemu-img is not installed.") %
+ image_meta['disk_format'],
+ image_id=image_id)
+ else:
+ raise exception.ImageUnacceptable(
+ reason=_("qemu-img is not installed and the disk "
+ "format is not specified. Only RAW images "
+ "can be used if qemu-img is not installed."),
+ image_id=image_id)
+
fetch(context, image_service, image_id, tmp, user_id, project_id)
if is_xenserver_image(context, image_service, image_id):
replace_xenserver_image_with_coalesced_vhd(tmp)
+ if no_qemu_img:
+ # qemu-img is not installed but we do have a RAW image. As a
+ # result we only need to copy the image to the destination and then
+ # return.
+ LOG.debug(_('Copying image from %(tmp)s to volume %(dest)s - '
+ 'size: %(size)s') % {'tmp': tmp, 'dest': dest,
+ 'size': image_meta['size']})
+ volume_utils.copy_volume(tmp, dest, image_meta['size'])
+ return
+
data = qemu_img_info(tmp)
fmt = data.file_format
if fmt is None:
(TEST_RET, 'ignored')
)
+ utils.execute(
+ 'env', 'LC_ALL=C', 'LANG=C', 'qemu-img', 'info',
+ self.TEST_DEV_PATH, run_as_root=True).AndReturn(
+ (TEST_RET, 'ignored')
+ )
+
utils.execute('qemu-img', 'convert', '-O', 'raw',
self.TEST_DEV_PATH, self.TEST_DEV_PATH, run_as_root=True)
(TEST_RET, 'ignored')
)
+ utils.execute(
+ 'env', 'LC_ALL=C', 'LANG=C', 'qemu-img', 'info',
+ self.TEST_DEV_PATH, run_as_root=True).AndReturn(
+ (TEST_RET, 'ignored')
+ )
+
mox.ReplayAll()
self.assertRaises(exception.ImageUnacceptable,
(TEST_RET, 'ignored')
)
+ utils.execute(
+ 'env', 'LC_ALL=C', 'LANG=C', 'qemu-img', 'info',
+ self.TEST_DEV_PATH, run_as_root=True).AndReturn(
+ (TEST_RET, 'ignored')
+ )
+
mox.ReplayAll()
self.assertRaises(exception.ImageUnacceptable,
image_utils.fetch_to_raw,
(TEST_RET, 'ignored')
)
+ utils.execute(
+ 'env', 'LC_ALL=C', 'LANG=C', 'qemu-img', 'info',
+ self.TEST_DEV_PATH, run_as_root=True).AndReturn(
+ (TEST_RET, 'ignored')
+ )
+
utils.execute('qemu-img', 'convert', '-O', 'raw',
self.TEST_DEV_PATH, self.TEST_DEV_PATH, run_as_root=True)