summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJenkins <jenkins@review.openstack.org>2016-10-05 00:56:31 +0000
committerGerrit Code Review <review@openstack.org>2016-10-05 00:56:31 +0000
commit618320782ea798e1ec6cba438a476ffa2ae47e61 (patch)
tree3fda676a9f4f84ffd193e784894b969739b93efc
parente7bf9d43bb47c2796d8ae3c46507a76c8a4bfddd (diff)
parent48d30c16d339c8d1218c3b85c9da7a69f7e99bb8 (diff)
downloadnova-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.py48
-rw-r--r--nova/virt/libvirt/driver.py29
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