diff options
author | Jenkins <jenkins@review.openstack.org> | 2016-10-05 00:56:31 +0000 |
---|---|---|
committer | Gerrit Code Review <review@openstack.org> | 2016-10-05 00:56:31 +0000 |
commit | 618320782ea798e1ec6cba438a476ffa2ae47e61 (patch) | |
tree | 3fda676a9f4f84ffd193e784894b969739b93efc | |
parent | e7bf9d43bb47c2796d8ae3c46507a76c8a4bfddd (diff) | |
parent | 48d30c16d339c8d1218c3b85c9da7a69f7e99bb8 (diff) | |
download | nova-618320782ea798e1ec6cba438a476ffa2ae47e61.tar.gz |
Merge "[libvirt] Live migration fails when config_drive_format=iso9660" into stable/mitaka
-rw-r--r-- | nova/tests/unit/virt/libvirt/test_driver.py | 48 | ||||
-rw-r--r-- | nova/virt/libvirt/driver.py | 29 |
2 files changed, 47 insertions, 30 deletions
diff --git a/nova/tests/unit/virt/libvirt/test_driver.py b/nova/tests/unit/virt/libvirt/test_driver.py index ab7e3fd29c..059999748f 100644 --- a/nova/tests/unit/virt/libvirt/test_driver.py +++ b/nova/tests/unit/virt/libvirt/test_driver.py @@ -81,7 +81,6 @@ from nova.tests.unit.virt.libvirt import fakelibvirt from nova import utils from nova import version from nova.virt import block_device as driver_block_device -from nova.virt import configdrive from nova.virt.disk import api as disk from nova.virt import driver from nova.virt import fake @@ -8510,27 +8509,48 @@ class LibvirtConnTestCase(test.NoDBTestCase): pre_migration_result=True)['pre_live_migration_result'], target_ret) - def test_pre_live_migration_block_with_config_drive_mocked(self): - # Creating testdata + @mock.patch.object(os, 'mkdir') + @mock.patch('nova.virt.libvirt.utils.get_instance_path_at_destination') + @mock.patch('nova.virt.libvirt.driver.remotefs.' + 'RemoteFilesystem.copy_file') + @mock.patch('nova.virt.driver.block_device_info_get_mapping') + @mock.patch('nova.virt.configdrive.required_by', return_value=True) + def test_pre_live_migration_block_with_config_drive_success( + self, mock_required_by, block_device_info_get_mapping, + mock_copy_file, mock_get_instance_path, mock_mkdir): + self.flags(config_drive_format='iso9660') vol = {'block_device_mapping': [ {'connection_info': 'dummy', 'mount_device': '/dev/sda'}, {'connection_info': 'dummy', 'mount_device': '/dev/sdb'}]} + fake_instance_path = os.path.join(cfg.CONF.instances_path, + '/fake_instance_uuid') + mock_get_instance_path.return_value = fake_instance_path + drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False) - def fake_true(*args, **kwargs): - return True + instance = objects.Instance(**self.test_instance) + migrate_data = objects.LibvirtLiveMigrateData() + migrate_data.is_shared_instance_path = False + migrate_data.is_shared_block_storage = False + migrate_data.block_migration = True + migrate_data.instance_relative_path = 'foo' + src = "%s:%s/disk.config" % (instance.host, fake_instance_path) - self.stubs.Set(configdrive, 'required_by', fake_true) + result = drvr.pre_live_migration( + self.context, instance, vol, [], None, migrate_data) - instance = objects.Instance(**self.test_instance) - c = context.get_admin_context() + block_device_info_get_mapping.assert_called_once_with( + {'block_device_mapping': [ + {'connection_info': 'dummy', 'mount_device': '/dev/sda'}, + {'connection_info': 'dummy', 'mount_device': '/dev/sdb'} + ]} + ) + mock_copy_file.assert_called_once_with(src, fake_instance_path) - self.assertRaises(exception.NoLiveMigrationForConfigDriveInLibVirt, - drvr.pre_live_migration, c, instance, vol, None, - None, {'is_shared_instance_path': False, - 'is_shared_block_storage': False, - 'block_migration': False, - 'instance_relative_path': 'foo'}) + migrate_data.graphics_listen_addrs_vnc = '127.0.0.1' + migrate_data.graphics_listen_addrs_spice = '127.0.0.1' + migrate_data.serial_listen_addr = '127.0.0.1' + self.assertEqual(migrate_data, result) @mock.patch('nova.virt.driver.block_device_info_get_mapping', return_value=()) diff --git a/nova/virt/libvirt/driver.py b/nova/virt/libvirt/driver.py index 61e64e5327..8c1e27a8c7 100644 --- a/nova/virt/libvirt/driver.py +++ b/nova/virt/libvirt/driver.py @@ -6640,22 +6640,6 @@ class LibvirtDriver(driver.ComputeDriver): is_shared_instance_path = migrate_data.is_shared_instance_path is_block_migration = migrate_data.block_migration - if configdrive.required_by(instance): - # NOTE(sileht): configdrive is stored into the block storage - # kvm is a block device, live migration will work - # NOTE(sileht): the configdrive is stored into a shared path - # kvm don't need to migrate it, live migration will work - # NOTE(dims): Using config drive with iso format does not work - # because of a bug in libvirt with read only devices. However - # one can use vfat as config_drive_format which works fine. - # Please see bug/1246201 for details on the libvirt bug. - if (is_shared_block_storage or - is_shared_instance_path or - CONF.config_drive_format == 'vfat'): - pass - else: - raise exception.NoLiveMigrationForConfigDriveInLibVirt() - if not is_shared_instance_path: instance_dir = libvirt_utils.get_instance_path_at_destination( instance, migrate_data) @@ -6692,6 +6676,19 @@ class LibvirtDriver(driver.ComputeDriver): self._create_images_and_backing( context, instance, instance_dir, disk_info, fallback_from_host=instance.host) + if (configdrive.required_by(instance) and + CONF.config_drive_format == 'iso9660'): + # NOTE(pkoniszewski): Due to a bug in libvirt iso config + # drive needs to be copied to destination prior to + # migration when instance path is not shared and block + # storage is not shared. Files that are already present + # on destination are excluded from a list of files that + # need to be copied to destination. If we don't do that + # live migration will fail on copying iso config drive to + # destination and writing to read-only device. + # Please see bug/1246201 for more details. + src = "%s:%s/disk.config" % (instance.host, instance_dir) + self._remotefs.copy_file(src, instance_dir) if not is_block_migration: # NOTE(angdraug): when block storage is shared between source |