libvirt: Get driver type from base image type.

If we are using the raw backend (no cow), we should set the driver
type based on the type of the source image instead of always
using raw.

Calls to to_xml were moved after _create_image so that the image
type could be determined when creating the xml for libvirt.

Fixes bug 1163009

Change-Id: Ic8d5f0ab83d868a42f834d39c0afb64818d7e027
This commit is contained in:
Vishvananda Ishaya
2013-04-01 14:19:49 -07:00
parent c8067d1b70
commit 494a3cb574
4 changed files with 51 additions and 18 deletions

View File

@@ -156,6 +156,7 @@ class RawTestCase(_ImageTestCase, test.TestCase):
def setUp(self):
self.image_class = imagebackend.Raw
super(RawTestCase, self).setUp()
self.stubs.Set(imagebackend.Raw, 'correct_format', lambda _: None)
def prepare_mocks(self):
fn = self.mox.CreateMockAnything()
@@ -198,6 +199,24 @@ class RawTestCase(_ImageTestCase, test.TestCase):
self.mox.VerifyAll()
def test_correct_format(self):
info = self.mox.CreateMockAnything()
self.stubs.UnsetAll()
self.mox.StubOutWithMock(os.path, 'exists')
self.mox.StubOutWithMock(imagebackend.images, 'qemu_img_info')
os.path.exists(self.PATH).AndReturn(True)
info = self.mox.CreateMockAnything()
info.file_format = 'foo'
imagebackend.images.qemu_img_info(self.PATH).AndReturn(info)
self.mox.ReplayAll()
image = self.image_class(self.INSTANCE, self.NAME, path=self.PATH)
self.assertEqual(image.driver_format, 'foo')
self.mox.VerifyAll()
class Qcow2TestCase(_ImageTestCase, test.TestCase):
SIZE = 1024 * 1024 * 1024

View File

@@ -2722,10 +2722,10 @@ class LibvirtConnTestCase(test.TestCase):
instance,
None,
image_meta)
conn._create_image(context, instance,
disk_info['mapping'])
xml = conn.to_xml(instance, None,
disk_info, image_meta)
conn._create_image(context, instance, xml,
disk_info['mapping'])
wantFiles = [
{'filename': '356a192b7913b04c54574d18c28d46e6395428ab',
@@ -2783,10 +2783,10 @@ class LibvirtConnTestCase(test.TestCase):
instance,
None,
image_meta)
conn._create_image(context, instance,
disk_info['mapping'])
xml = conn.to_xml(instance, None,
disk_info, image_meta)
conn._create_image(context, instance, xml,
disk_info['mapping'])
wantFiles = [
{'filename': '356a192b7913b04c54574d18c28d46e6395428ab',
@@ -4879,7 +4879,7 @@ class LibvirtDriverTestCase(test.TestCase):
def fake_plug_vifs(instance, network_info):
pass
def fake_create_image(context, inst, libvirt_xml,
def fake_create_image(context, inst,
disk_mapping, suffix='',
disk_images=None, network_info=None,
block_device_info=None):

View File

@@ -1356,6 +1356,12 @@ class LibvirtDriver(driver.ComputeDriver):
disk_info = blockinfo.get_disk_info(CONF.libvirt_type,
instance,
block_device_info)
# NOTE(vish): This could generate the wrong device_format if we are
# using the raw backend and the images don't exist yet.
# The create_images_and_backing below doesn't properly
# regenerate raw backend images, however, so when it
# does we need to (re)generate the xml after the images
# are in place.
xml = self.to_xml(instance, network_info, disk_info,
block_device_info=block_device_info,
write_to_disk=True)
@@ -1461,13 +1467,14 @@ class LibvirtDriver(driver.ComputeDriver):
None,
image_meta,
rescue=True)
xml = self.to_xml(instance, network_info, disk_info,
image_meta, rescue=rescue_images)
self._create_image(context, instance, xml,
self._create_image(context, instance,
disk_info['mapping'],
'.rescue', rescue_images,
network_info=network_info,
admin_pass=rescue_password)
xml = self.to_xml(instance, network_info, disk_info,
image_meta, rescue=rescue_images,
write_to_disk=True)
self._destroy(instance)
self._create_domain(xml)
@@ -1505,16 +1512,16 @@ class LibvirtDriver(driver.ComputeDriver):
instance,
block_device_info,
image_meta)
xml = self.to_xml(instance, network_info,
disk_info, image_meta,
block_device_info=block_device_info)
self._create_image(context, instance, xml,
self._create_image(context, instance,
disk_info['mapping'],
network_info=network_info,
block_device_info=block_device_info,
files=injected_files,
admin_pass=admin_password)
xml = self.to_xml(instance, network_info,
disk_info, image_meta,
block_device_info=block_device_info,
write_to_disk=True)
self._create_domain_and_network(xml, instance, network_info,
block_device_info)
@@ -1720,7 +1727,7 @@ class LibvirtDriver(driver.ComputeDriver):
if os.path.exists(console_log):
libvirt_utils.chown(console_log, os.getuid())
def _create_image(self, context, instance, libvirt_xml,
def _create_image(self, context, instance,
disk_mapping, suffix='',
disk_images=None, network_info=None,
block_device_info=None, files=None, admin_pass=None):
@@ -1748,7 +1755,6 @@ class LibvirtDriver(driver.ComputeDriver):
fileutils.ensure_tree(basepath(suffix=''))
LOG.info(_('Creating image'), instance=instance)
libvirt_utils.write_to_file(basepath('libvirt.xml'), libvirt_xml)
# NOTE(dprince): for rescue console.log may already exist... chown it.
self._chown_console_log_for_instance(instance)
@@ -3524,14 +3530,15 @@ class LibvirtDriver(driver.ComputeDriver):
instance,
block_device_info,
image_meta)
xml = self.to_xml(instance, network_info, disk_info,
block_device_info=block_device_info)
# assume _create_image do nothing if a target file exists.
# TODO(oda): injecting files is not necessary
self._create_image(context, instance, xml,
self._create_image(context, instance,
disk_mapping=disk_info['mapping'],
network_info=network_info,
block_device_info=None)
xml = self.to_xml(instance, network_info, disk_info,
block_device_info=block_device_info,
write_to_disk=True)
self._create_domain_and_network(xml, instance, network_info,
block_device_info)
timer = utils.FixedIntervalLoopingCall(self._wait_for_running,

View File

@@ -195,6 +195,12 @@ class Raw(Image):
disk_name))
self.snapshot_name = snapshot_name
self.preallocate = CONF.preallocate_images != 'none'
self.correct_format()
def correct_format(self):
if os.path.exists(self.path):
data = images.qemu_img_info(self.path)
self.driver_format = data.file_format or 'raw'
def create_image(self, prepare_template, base, size, *args, **kwargs):
@lockutils.synchronized(base, 'nova-', external=True,
@@ -213,6 +219,7 @@ class Raw(Image):
if not os.path.exists(self.path):
with utils.remove_path_on_error(self.path):
copy_raw_image(base, self.path, size)
self.correct_format()
def snapshot_create(self):
pass