diff --git a/nova/tests/unit/virt/libvirt/test_driver.py b/nova/tests/unit/virt/libvirt/test_driver.py index bfbe32d04923..60c16c3d1177 100644 --- a/nova/tests/unit/virt/libvirt/test_driver.py +++ b/nova/tests/unit/virt/libvirt/test_driver.py @@ -13765,6 +13765,36 @@ class LibvirtConnTestCase(test.NoDBTestCase): self._test_get_guest_config_parallels_volume(vm_mode.EXE, 4) self._test_get_guest_config_parallels_volume(vm_mode.HVM, 6) + def test_get_guest_disk_config_rbd_older_config_drive_fall_back(self): + # New config drives are stored in rbd but existing instances have + # config drives in the old location under the instances path. + # Test that the driver falls back to 'flat' for config drive if it + # doesn't exist in rbd. + self.flags(images_type='rbd', group='libvirt') + drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False) + drvr.image_backend = mock.Mock() + mock_rbd_image = mock.Mock() + mock_flat_image = mock.Mock() + mock_flat_image.libvirt_info.return_value = mock.sentinel.diskconfig + drvr.image_backend.image.side_effect = [mock_rbd_image, + mock_flat_image] + mock_rbd_image.exists.return_value = False + instance = objects.Instance() + disk_mapping = {'disk.config': {'bus': 'ide', + 'dev': 'hdd', + 'type': 'file'}} + flavor = objects.Flavor(extra_specs={}) + + diskconfig = drvr._get_guest_disk_config( + instance, 'disk.config', disk_mapping, flavor, + drvr._get_disk_config_image_type()) + + self.assertEqual(2, drvr.image_backend.image.call_count) + call1 = mock.call(instance, 'disk.config', 'rbd') + call2 = mock.call(instance, 'disk.config', 'flat') + drvr.image_backend.image.assert_has_calls([call1, call2]) + self.assertEqual(mock.sentinel.diskconfig, diskconfig) + def _test_prepare_domain_for_snapshot(self, live_snapshot, state): drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False) instance_ref = objects.Instance(**self.test_instance) diff --git a/nova/virt/libvirt/driver.py b/nova/virt/libvirt/driver.py index fae159b325bf..e82206c4b0ba 100644 --- a/nova/virt/libvirt/driver.py +++ b/nova/virt/libvirt/driver.py @@ -3327,6 +3327,15 @@ class LibvirtDriver(driver.ComputeDriver): image = self.image_backend.image(instance, name, image_type) + if (name == 'disk.config' and image_type == 'rbd' and + not image.exists()): + # This is likely an older config drive that has not been migrated + # to rbd yet. Try to fall back on 'flat' image type. + # TODO(melwitt): Add online migration of some sort so we can + # remove this fall back once we know all config drives are in rbd. + image = self.image_backend.image(instance, name, 'flat') + LOG.debug('Config drive not found in RBD, falling back to the ' + 'instance directory', instance=instance) disk_info = disk_mapping[name] return image.libvirt_info(disk_info['bus'], disk_info['dev'],