Libvirt: Added suffix to configdrive_path required for rescue
It was observed that during nova rescue, nova failed to create a rescue disk for disk.config. The reason being that .rescue suffix was missing from the configdrive path. It was working till Havana but the functionality broke in Icehouse. This commit fixes the suffix problem. Unittests have been added to verify following scenarios: 1. Make sure that .rescue disks are created when not using config drive 2. Make sure that .rescue disks are created when using config drive Closes-Bug: #1334024 Change-Id: I87449ffddd047cb84b7b881757ea4c29927b95da
This commit is contained in:
parent
b16db2bdca
commit
0d781d41fe
|
@ -56,3 +56,18 @@ class Backend(object):
|
|||
#NOTE(bfilippov): this is done in favor for
|
||||
# snapshot tests in test_libvirt.LibvirtConnTestCase
|
||||
return imagebackend.Backend(True).snapshot(path, image_type)
|
||||
|
||||
|
||||
class Raw(imagebackend.Image):
|
||||
# NOTE(spandhe) Added for test_rescue and test_rescue_config_drive
|
||||
def __init__(self, instance=None, disk_name=None, path=None):
|
||||
pass
|
||||
|
||||
def _get_driver_format(self):
|
||||
pass
|
||||
|
||||
def correct_format(self):
|
||||
pass
|
||||
|
||||
def create_image(self, prepare_template, base, size, *args, **kwargs):
|
||||
pass
|
||||
|
|
|
@ -32,6 +32,7 @@ from oslo.config import cfg
|
|||
from xml.dom import minidom
|
||||
|
||||
from nova.api.ec2 import cloud
|
||||
from nova.api.metadata import base as instance_metadata
|
||||
from nova.compute import flavors
|
||||
from nova.compute import manager
|
||||
from nova.compute import power_state
|
||||
|
@ -61,6 +62,7 @@ from nova.tests import fake_network
|
|||
import nova.tests.image.fake
|
||||
from nova.tests import matchers
|
||||
from nova.tests.objects import test_pci_device
|
||||
from nova.tests.virt.libvirt import fake_imagebackend
|
||||
from nova.tests.virt.libvirt import fake_libvirt_utils
|
||||
from nova.tests.virt.libvirt import fakelibvirt
|
||||
from nova import utils
|
||||
|
@ -5199,7 +5201,7 @@ class LibvirtConnTestCase(test.TestCase):
|
|||
).AndReturn(instance)
|
||||
self.mox.StubOutWithMock(driver, "block_device_info_get_mapping")
|
||||
driver.block_device_info_get_mapping(vol
|
||||
).AndReturn(vol['block_device_mapping'])
|
||||
).AndReturn(vol['block_device_mapping'])
|
||||
self.mox.StubOutWithMock(libvirt_driver.LibvirtDriver,
|
||||
"volume_driver_method")
|
||||
if volume_fail:
|
||||
|
@ -9281,6 +9283,156 @@ class LibvirtDriverTestCase(test.TestCase):
|
|||
'detach_interface', power_state.SHUTDOWN,
|
||||
expected_flags=(libvirt.VIR_DOMAIN_AFFECT_CONFIG))
|
||||
|
||||
def test_rescue(self):
|
||||
instance = self._create_instance()
|
||||
instance.config_drive = False
|
||||
dummyxml = ("<domain type='kvm'><name>instance-0000000a</name>"
|
||||
"<devices>"
|
||||
"<disk type='file'><driver name='qemu' type='raw'/>"
|
||||
"<source file='/test/disk'/>"
|
||||
"<target dev='vda' bus='virtio'/></disk>"
|
||||
"<disk type='file'><driver name='qemu' type='qcow2'/>"
|
||||
"<source file='/test/disk.local'/>"
|
||||
"<target dev='vdb' bus='virtio'/></disk>"
|
||||
"</devices></domain>")
|
||||
network_info = _fake_network_info(self.stubs, 1)
|
||||
|
||||
self.mox.StubOutWithMock(self.libvirtconnection,
|
||||
'_get_existing_domain_xml')
|
||||
self.mox.StubOutWithMock(libvirt_utils, 'write_to_file')
|
||||
self.mox.StubOutWithMock(imagebackend.Backend, 'image')
|
||||
self.mox.StubOutWithMock(imagebackend.Image, 'cache')
|
||||
self.mox.StubOutWithMock(self.libvirtconnection, '_get_guest_xml')
|
||||
self.mox.StubOutWithMock(self.libvirtconnection, '_destroy')
|
||||
self.mox.StubOutWithMock(self.libvirtconnection, '_create_domain')
|
||||
|
||||
self.libvirtconnection._get_existing_domain_xml(mox.IgnoreArg(),
|
||||
mox.IgnoreArg()).MultipleTimes().AndReturn(dummyxml)
|
||||
libvirt_utils.write_to_file(mox.IgnoreArg(), mox.IgnoreArg())
|
||||
libvirt_utils.write_to_file(mox.IgnoreArg(), mox.IgnoreArg(),
|
||||
mox.IgnoreArg())
|
||||
imagebackend.Backend.image(instance, 'kernel.rescue', 'raw'
|
||||
).AndReturn(fake_imagebackend.Raw())
|
||||
imagebackend.Backend.image(instance, 'ramdisk.rescue', 'raw'
|
||||
).AndReturn(fake_imagebackend.Raw())
|
||||
imagebackend.Backend.image(instance, 'disk.rescue', 'default'
|
||||
).AndReturn(fake_imagebackend.Raw())
|
||||
imagebackend.Image.cache(context=mox.IgnoreArg(),
|
||||
fetch_func=mox.IgnoreArg(),
|
||||
filename=mox.IgnoreArg(),
|
||||
image_id=mox.IgnoreArg(),
|
||||
project_id=mox.IgnoreArg(),
|
||||
user_id=mox.IgnoreArg()).MultipleTimes()
|
||||
|
||||
imagebackend.Image.cache(context=mox.IgnoreArg(),
|
||||
fetch_func=mox.IgnoreArg(),
|
||||
filename=mox.IgnoreArg(),
|
||||
image_id=mox.IgnoreArg(),
|
||||
project_id=mox.IgnoreArg(),
|
||||
size=None, user_id=mox.IgnoreArg())
|
||||
|
||||
image_meta = {'id': 'fake', 'name': 'fake'}
|
||||
self.libvirtconnection._get_guest_xml(mox.IgnoreArg(), instance,
|
||||
network_info, mox.IgnoreArg(),
|
||||
image_meta, rescue=mox.IgnoreArg(),
|
||||
write_to_disk=mox.IgnoreArg()
|
||||
).AndReturn(dummyxml)
|
||||
|
||||
self.libvirtconnection._destroy(instance)
|
||||
self.libvirtconnection._create_domain(mox.IgnoreArg())
|
||||
|
||||
self.mox.ReplayAll()
|
||||
|
||||
rescue_password = 'fake_password'
|
||||
|
||||
self.libvirtconnection.rescue(self.context, instance,
|
||||
network_info, image_meta, rescue_password)
|
||||
self.mox.VerifyAll()
|
||||
|
||||
def test_rescue_config_drive(self):
|
||||
instance = self._create_instance()
|
||||
uuid = instance.uuid
|
||||
configdrive_path = uuid + '/disk.config.rescue'
|
||||
dummyxml = ("<domain type='kvm'><name>instance-0000000a</name>"
|
||||
"<devices>"
|
||||
"<disk type='file'><driver name='qemu' type='raw'/>"
|
||||
"<source file='/test/disk'/>"
|
||||
"<target dev='vda' bus='virtio'/></disk>"
|
||||
"<disk type='file'><driver name='qemu' type='qcow2'/>"
|
||||
"<source file='/test/disk.local'/>"
|
||||
"<target dev='vdb' bus='virtio'/></disk>"
|
||||
"</devices></domain>")
|
||||
network_info = _fake_network_info(self.stubs, 1)
|
||||
|
||||
self.mox.StubOutWithMock(self.libvirtconnection,
|
||||
'_get_existing_domain_xml')
|
||||
self.mox.StubOutWithMock(libvirt_utils, 'write_to_file')
|
||||
self.mox.StubOutWithMock(imagebackend.Backend, 'image')
|
||||
self.mox.StubOutWithMock(imagebackend.Image, 'cache')
|
||||
self.mox.StubOutWithMock(instance_metadata.InstanceMetadata,
|
||||
'__init__')
|
||||
self.mox.StubOutWithMock(configdrive, 'ConfigDriveBuilder')
|
||||
self.mox.StubOutWithMock(configdrive.ConfigDriveBuilder, 'make_drive')
|
||||
self.mox.StubOutWithMock(self.libvirtconnection, '_get_guest_xml')
|
||||
self.mox.StubOutWithMock(self.libvirtconnection, '_destroy')
|
||||
self.mox.StubOutWithMock(self.libvirtconnection, '_create_domain')
|
||||
|
||||
self.libvirtconnection._get_existing_domain_xml(mox.IgnoreArg(),
|
||||
mox.IgnoreArg()).MultipleTimes().AndReturn(dummyxml)
|
||||
libvirt_utils.write_to_file(mox.IgnoreArg(), mox.IgnoreArg())
|
||||
libvirt_utils.write_to_file(mox.IgnoreArg(), mox.IgnoreArg(),
|
||||
mox.IgnoreArg())
|
||||
|
||||
imagebackend.Backend.image(instance, 'kernel.rescue', 'raw'
|
||||
).AndReturn(fake_imagebackend.Raw())
|
||||
imagebackend.Backend.image(instance, 'ramdisk.rescue', 'raw'
|
||||
).AndReturn(fake_imagebackend.Raw())
|
||||
imagebackend.Backend.image(instance, 'disk.rescue', 'default'
|
||||
).AndReturn(fake_imagebackend.Raw())
|
||||
|
||||
imagebackend.Image.cache(context=mox.IgnoreArg(),
|
||||
fetch_func=mox.IgnoreArg(),
|
||||
filename=mox.IgnoreArg(),
|
||||
image_id=mox.IgnoreArg(),
|
||||
project_id=mox.IgnoreArg(),
|
||||
user_id=mox.IgnoreArg()).MultipleTimes()
|
||||
|
||||
imagebackend.Image.cache(context=mox.IgnoreArg(),
|
||||
fetch_func=mox.IgnoreArg(),
|
||||
filename=mox.IgnoreArg(),
|
||||
image_id=mox.IgnoreArg(),
|
||||
project_id=mox.IgnoreArg(),
|
||||
size=None, user_id=mox.IgnoreArg())
|
||||
|
||||
instance_metadata.InstanceMetadata.__init__(mox.IgnoreArg(),
|
||||
content=mox.IgnoreArg(),
|
||||
extra_md=mox.IgnoreArg(),
|
||||
network_info=mox.IgnoreArg())
|
||||
cdb = self.mox.CreateMockAnything()
|
||||
m = configdrive.ConfigDriveBuilder(instance_md=mox.IgnoreArg())
|
||||
m.AndReturn(cdb)
|
||||
# __enter__ and __exit__ are required by "with"
|
||||
cdb.__enter__().AndReturn(cdb)
|
||||
cdb.make_drive(mox.Regex(configdrive_path))
|
||||
cdb.__exit__(mox.IgnoreArg(), mox.IgnoreArg(), mox.IgnoreArg()
|
||||
).AndReturn(None)
|
||||
image_meta = {'id': 'fake', 'name': 'fake'}
|
||||
self.libvirtconnection._get_guest_xml(mox.IgnoreArg(), instance,
|
||||
network_info, mox.IgnoreArg(),
|
||||
image_meta, rescue=mox.IgnoreArg(),
|
||||
write_to_disk=mox.IgnoreArg()
|
||||
).AndReturn(dummyxml)
|
||||
self.libvirtconnection._destroy(instance)
|
||||
self.libvirtconnection._create_domain(mox.IgnoreArg())
|
||||
|
||||
self.mox.ReplayAll()
|
||||
|
||||
rescue_password = 'fake_password'
|
||||
|
||||
self.libvirtconnection.rescue(self.context, instance, network_info,
|
||||
image_meta, rescue_password)
|
||||
self.mox.VerifyAll()
|
||||
|
||||
|
||||
class LibvirtVolumeUsageTestCase(test.TestCase):
|
||||
"""Test for LibvirtDriver.get_all_volume_usage."""
|
||||
|
|
|
@ -2457,9 +2457,9 @@ class LibvirtDriver(driver.ComputeDriver):
|
|||
'console.log')
|
||||
|
||||
@staticmethod
|
||||
def _get_disk_config_path(instance):
|
||||
def _get_disk_config_path(instance, suffix=''):
|
||||
return os.path.join(libvirt_utils.get_instance_path(instance),
|
||||
'disk.config')
|
||||
'disk.config' + suffix)
|
||||
|
||||
def _chown_console_log_for_instance(self, instance):
|
||||
console_log = self._get_console_log_path(instance)
|
||||
|
@ -2682,7 +2682,7 @@ class LibvirtDriver(driver.ComputeDriver):
|
|||
inst_md = instance_metadata.InstanceMetadata(instance,
|
||||
content=files, extra_md=extra_md, network_info=network_info)
|
||||
with configdrive.ConfigDriveBuilder(instance_md=inst_md) as cdb:
|
||||
configdrive_path = self._get_disk_config_path(instance)
|
||||
configdrive_path = self._get_disk_config_path(instance, suffix)
|
||||
LOG.info(_LI('Creating config drive at %(path)s'),
|
||||
{'path': configdrive_path}, instance=instance)
|
||||
|
||||
|
|
Loading…
Reference in New Issue