diff options
author | Daniel P. Berrange <berrange@redhat.com> | 2013-02-21 19:33:23 +0000 |
---|---|---|
committer | Daniel P. Berrange <berrange@redhat.com> | 2013-02-21 19:44:35 +0000 |
commit | 78126baa70f9f05ae9fd9f7423da4ea0ba45c49c (patch) | |
tree | 9b3e16a3d6ad2c24cef891e0733426b23b27981d | |
parent | 0f0a8c6bcce1b230a5719b35089f25e55a1359a8 (diff) | |
download | nova-78126baa70f9f05ae9fd9f7423da4ea0ba45c49c.tar.gz nova-78126baa70f9f05ae9fd9f7423da4ea0ba45c49c.tar.xz nova-78126baa70f9f05ae9fd9f7423da4ea0ba45c49c.zip |
Fix launching libvirt instances with swap
The code in
commit 7be531fe9462f2b07d4a1abf6687f649d1dfbb89
Author: Daniel P. Berrange <berrange@redhat.com>
Date: Tue Jan 15 20:43:48 2013 +0000
Refactor code for setting up libvirt disk mappings
accidentally broken launching of instances where
the flavor had non-zero swap specified. This was
not caught due to complete lack of test coverage
for the '_create_image' method. This adds two
test cases for that method, exercising this bug.
It also fixes a bug in netutils which was not
handling a NULL network mapping, which is a valid
scenario for several callers.
Fixes bug #1131306
Change-Id: I214561ba3ec6440d11a5afb0665e6b6f990bd148
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
-rw-r--r-- | nova/tests/test_libvirt.py | 123 | ||||
-rwxr-xr-x | nova/virt/libvirt/driver.py | 3 | ||||
-rw-r--r-- | nova/virt/netutils.py | 3 |
3 files changed, 128 insertions, 1 deletions
diff --git a/nova/tests/test_libvirt.py b/nova/tests/test_libvirt.py index 945d627f4..b1135902d 100644 --- a/nova/tests/test_libvirt.py +++ b/nova/tests/test_libvirt.py @@ -2569,6 +2569,129 @@ class LibvirtConnTestCase(test.TestCase): None) self.assertTrue(self.create_image_called) + def test_create_image_plain(self): + gotFiles = [] + + def fake_image(self, instance, name, image_type=''): + class FakeImage(imagebackend.Image): + def __init__(self, instance, name): + self.path = os.path.join(instance['name'], name) + + def create_image(self, prepare_template, base, + size, *args, **kwargs): + pass + + def cache(self, fetch_func, filename, size=None, + *args, **kwargs): + gotFiles.append({'filename': filename, + 'size': size}) + + def snapshot(self, name): + pass + + return FakeImage(instance, name) + + def fake_none(*args, **kwargs): + return + + def fake_get_info(instance): + return {'state': power_state.RUNNING} + + # Stop 'libvirt_driver._create_image' touching filesystem + self.stubs.Set(nova.virt.libvirt.imagebackend.Backend, "image", + fake_image) + + instance_ref = self.test_instance + instance_ref['image_ref'] = 1 + instance = db.instance_create(self.context, instance_ref) + + conn = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False) + self.stubs.Set(conn, 'to_xml', fake_none) + self.stubs.Set(conn, '_create_domain_and_network', fake_none) + self.stubs.Set(conn, 'get_info', fake_get_info) + + image_meta = {'id': instance['image_ref']} + disk_info = blockinfo.get_disk_info(CONF.libvirt_type, + instance, + None, + image_meta) + xml = conn.to_xml(instance, None, + disk_info, image_meta) + conn._create_image(context, instance, xml, + disk_info['mapping']) + + wantFiles = [ + {'filename': '356a192b7913b04c54574d18c28d46e6395428ab', + 'size': 10 * 1024 * 1024 * 1024}, + {'filename': 'ephemeral_20_default', + 'size': 20 * 1024 * 1024 * 1024}, + ] + self.assertEquals(gotFiles, wantFiles) + + def test_create_image_with_swap(self): + gotFiles = [] + + def fake_image(self, instance, name, image_type=''): + class FakeImage(imagebackend.Image): + def __init__(self, instance, name): + self.path = os.path.join(instance['name'], name) + + def create_image(self, prepare_template, base, + size, *args, **kwargs): + pass + + def cache(self, fetch_func, filename, size=None, + *args, **kwargs): + gotFiles.append({'filename': filename, + 'size': size}) + + def snapshot(self, name): + pass + + return FakeImage(instance, name) + + def fake_none(*args, **kwargs): + return + + def fake_get_info(instance): + return {'state': power_state.RUNNING} + + # Stop 'libvirt_driver._create_image' touching filesystem + self.stubs.Set(nova.virt.libvirt.imagebackend.Backend, "image", + fake_image) + + instance_ref = self.test_instance + instance_ref['image_ref'] = 1 + instance = db.instance_create(self.context, instance_ref) + + # Turn on some swap to exercise that codepath in _create_image + instance['instance_type']['swap'] = 500 + + conn = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False) + self.stubs.Set(conn, 'to_xml', fake_none) + self.stubs.Set(conn, '_create_domain_and_network', fake_none) + self.stubs.Set(conn, 'get_info', fake_get_info) + + image_meta = {'id': instance['image_ref']} + disk_info = blockinfo.get_disk_info(CONF.libvirt_type, + instance, + None, + image_meta) + xml = conn.to_xml(instance, None, + disk_info, image_meta) + conn._create_image(context, instance, xml, + disk_info['mapping']) + + wantFiles = [ + {'filename': '356a192b7913b04c54574d18c28d46e6395428ab', + 'size': 10 * 1024 * 1024 * 1024}, + {'filename': 'ephemeral_20_default', + 'size': 20 * 1024 * 1024 * 1024}, + {'filename': 'swap_500', + 'size': 500 * 1024 * 1024}, + ] + self.assertEquals(gotFiles, wantFiles) + def test_get_console_output_file(self): fake_libvirt_utils.files['console.log'] = '01234567890' diff --git a/nova/virt/libvirt/driver.py b/nova/virt/libvirt/driver.py index bcbd1de87..dfae88c23 100755 --- a/nova/virt/libvirt/driver.py +++ b/nova/virt/libvirt/driver.py @@ -1780,6 +1780,7 @@ class LibvirtDriver(driver.ComputeDriver): ephemeral_size=eph['size']) if 'disk.swap' in disk_mapping: + mapping = disk_mapping['disk.swap'] swap_mb = 0 swap = driver.block_device_info_get_swap(block_device_info) @@ -1787,7 +1788,7 @@ class LibvirtDriver(driver.ComputeDriver): swap_mb = swap['swap_size'] elif (inst_type['swap'] > 0 and not block_device.volume_in_mapping( - swap['dev'], block_device_info)): + mapping['dev'], block_device_info)): swap_mb = inst_type['swap'] if swap_mb > 0: diff --git a/nova/virt/netutils.py b/nova/virt/netutils.py index eec2d6467..1277251b5 100644 --- a/nova/virt/netutils.py +++ b/nova/virt/netutils.py @@ -67,6 +67,9 @@ def get_injected_network_template(network_info, use_ipv6=CONF.use_ipv6, convert the type itself if necessary. """ + if network_info is None: + return None + # the code below depends on the legacy 'network_info' if hasattr(network_info, 'legacy'): network_info = network_info.legacy() |