summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--nova/tests/test_libvirt.py55
-rwxr-xr-xnova/virt/libvirt/driver.py36
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,