diff options
-rw-r--r-- | nova/tests/test_libvirt.py | 55 | ||||
-rwxr-xr-x | nova/virt/libvirt/driver.py | 36 |
2 files changed, 77 insertions, 14 deletions
diff --git a/nova/tests/test_libvirt.py b/nova/tests/test_libvirt.py index 351c6b7dd..55b6aaec4 100644 --- a/nova/tests/test_libvirt.py +++ b/nova/tests/test_libvirt.py @@ -2578,7 +2578,7 @@ class LibvirtConnTestCase(test.TestCase): self.stubs.Set(conn, 'get_info', fake_get_info) conn.spawn(self.context, instance, None, [], None) - self.assertFalse(self.create_image_called) + self.assertTrue(self.create_image_called) conn.spawn(self.context, instance, @@ -2587,6 +2587,59 @@ class LibvirtConnTestCase(test.TestCase): None) self.assertTrue(self.create_image_called) + def test_spawn_from_volume_calls_cache(self): + self.cache_called_for_disk = False + + def fake_none(*args, **kwargs): + return + + def fake_cache(*args, **kwargs): + if kwargs.get('image_id') == 'my_fake_image': + self.cache_called_for_disk = True + + def fake_get_info(instance): + return {'state': power_state.RUNNING} + + conn = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False) + self.stubs.Set(conn, 'to_xml', fake_none) + + self.stubs.Set(imagebackend.Image, 'cache', fake_cache) + self.stubs.Set(conn, '_create_domain_and_network', fake_none) + self.stubs.Set(conn, 'get_info', fake_get_info) + + block_device_info = {'root_device_name': '/dev/vda', + 'block_device_mapping': [ + {'mount_device': 'vda'}]} + + # Volume-backed instance created without image + instance_ref = self.test_instance + instance_ref['image_ref'] = '' + instance_ref['root_device_name'] = '/dev/vda' + instance = db.instance_create(self.context, instance_ref) + + conn.spawn(self.context, instance, None, [], None, + block_device_info=block_device_info) + self.assertFalse(self.cache_called_for_disk) + db.instance_destroy(self.context, instance['uuid']) + + # Booted from volume but with placeholder image + instance_ref = self.test_instance + instance_ref['image_ref'] = 'my_fake_image' + instance_ref['root_device_name'] = '/dev/vda' + instance = db.instance_create(self.context, instance_ref) + + conn.spawn(self.context, instance, None, [], None, + block_device_info=block_device_info) + self.assertFalse(self.cache_called_for_disk) + db.instance_destroy(self.context, instance['uuid']) + + # Booted from an image + instance_ref['image_ref'] = 'my_fake_image' + instance = db.instance_create(self.context, instance_ref) + conn.spawn(self.context, instance, None, [], None) + self.assertTrue(self.cache_called_for_disk) + db.instance_destroy(self.context, instance['uuid']) + def test_create_image_plain(self): gotFiles = [] diff --git a/nova/virt/libvirt/driver.py b/nova/virt/libvirt/driver.py index 7960da90f..5e6b0e742 100755 --- a/nova/virt/libvirt/driver.py +++ b/nova/virt/libvirt/driver.py @@ -1507,13 +1507,14 @@ class LibvirtDriver(driver.ComputeDriver): xml = self.to_xml(instance, network_info, disk_info, image_meta, block_device_info=block_device_info) - if image_meta: - self._create_image(context, instance, xml, - disk_info['mapping'], - network_info=network_info, - block_device_info=block_device_info, - files=injected_files, - admin_pass=admin_password) + + self._create_image(context, instance, xml, + disk_info['mapping'], + network_info=network_info, + block_device_info=block_device_info, + files=injected_files, + admin_pass=admin_password) + self._create_domain_and_network(xml, instance, network_info, block_device_info) LOG.debug(_("Instance is running"), instance=instance) @@ -1725,6 +1726,11 @@ class LibvirtDriver(driver.ComputeDriver): if not suffix: suffix = '' + booted_from_volume = ( + (not bool(instance.get('image_ref'))) + or 'disk' not in disk_mapping + ) + # syntactic nicety def basepath(fname='', suffix=suffix): return os.path.join(libvirt_utils.get_instance_path(instance), @@ -1772,14 +1778,18 @@ class LibvirtDriver(driver.ComputeDriver): user_id=instance['user_id'], project_id=instance['project_id']) - root_fname = imagecache.get_cache_fname(disk_images, 'image_id') - size = instance['root_gb'] * 1024 * 1024 * 1024 - inst_type = instance_types.extract_instance_type(instance) - if size == 0 or suffix == '.rescue': - size = None - if 'disk' in disk_mapping: + # NOTE(ndipanov): Even if disk_mapping was passed in, which + # currently happens only on rescue - we still don't want to + # create a base image. + if not booted_from_volume: + root_fname = imagecache.get_cache_fname(disk_images, 'image_id') + size = instance['root_gb'] * 1024 * 1024 * 1024 + + if size == 0 or suffix == '.rescue': + size = None + image('disk').cache(fetch_func=libvirt_utils.fetch_image, context=context, filename=root_fname, |