Merge "libvirt: Remove redundant bdm serial mangling and saving during swap_volume" into stable/ocata
This commit is contained in:
commit
1e610e3ec9
|
@ -4958,7 +4958,11 @@ class ComputeManager(manager.Manager):
|
|||
old_cinfo = jsonutils.loads(bdm['connection_info'])
|
||||
if old_cinfo and 'serial' not in old_cinfo:
|
||||
old_cinfo['serial'] = old_volume_id
|
||||
new_cinfo['serial'] = old_cinfo['serial']
|
||||
# NOTE(lyarwood): serial is not always present in the returned
|
||||
# connection_info so set it if it is missing as we do in
|
||||
# DriverVolumeBlockDevice.attach().
|
||||
if 'serial' not in new_cinfo:
|
||||
new_cinfo['serial'] = new_volume_id
|
||||
return (old_cinfo, new_cinfo)
|
||||
|
||||
def _swap_volume(self, context, instance, bdm, connector,
|
||||
|
@ -4973,6 +4977,10 @@ class ComputeManager(manager.Manager):
|
|||
connector,
|
||||
instance,
|
||||
bdm)
|
||||
# NOTE(lyarwood): The Libvirt driver, the only virt driver
|
||||
# currently implementing swap_volume, will modify the contents of
|
||||
# new_cinfo when connect_volume is called. This is then saved to
|
||||
# the BDM in swap_volume for future use outside of this flow.
|
||||
LOG.debug("swap_volume: Calling driver volume swap with "
|
||||
"connection infos: new: %(new_cinfo)s; "
|
||||
"old: %(old_cinfo)s",
|
||||
|
@ -4980,6 +4988,9 @@ class ComputeManager(manager.Manager):
|
|||
instance=instance)
|
||||
self.driver.swap_volume(old_cinfo, new_cinfo, instance, mountpoint,
|
||||
resize_to)
|
||||
LOG.debug("swap_volume: Driver volume swap returned, new "
|
||||
"connection_info is now : %(new_cinfo)s",
|
||||
{'new_cinfo': new_cinfo})
|
||||
except Exception as ex:
|
||||
failed = True
|
||||
with excutils.save_and_reraise_exception():
|
||||
|
@ -5011,8 +5022,13 @@ class ComputeManager(manager.Manager):
|
|||
self.volume_api.terminate_connection(context,
|
||||
conn_volume,
|
||||
connector)
|
||||
# If Cinder initiated the swap, it will keep
|
||||
# the original ID
|
||||
# NOTE(lyarwood): The following call to
|
||||
# os-migrate-volume-completion returns a dict containing
|
||||
# save_volume_id, this volume id has two possible values :
|
||||
# 1. old_volume_id if we are migrating (retyping) volumes
|
||||
# 2. new_volume_id if we are swapping between two existing volumes
|
||||
# This volume id is later used to update the volume_id and
|
||||
# connection_info['serial'] of the BDM.
|
||||
comp_ret = self.volume_api.migrate_volume_completion(
|
||||
context,
|
||||
old_volume_id,
|
||||
|
@ -5057,9 +5073,10 @@ class ComputeManager(manager.Manager):
|
|||
new_volume_id,
|
||||
resize_to)
|
||||
|
||||
# NOTE(lyarwood): Update the BDM with the modified new_cinfo and
|
||||
# correct volume_id returned by Cinder.
|
||||
save_volume_id = comp_ret['save_volume_id']
|
||||
|
||||
# Update bdm
|
||||
new_cinfo['serial'] = save_volume_id
|
||||
values = {
|
||||
'connection_info': jsonutils.dumps(new_cinfo),
|
||||
'source_type': 'volume',
|
||||
|
|
|
@ -1943,7 +1943,7 @@ class ComputeManagerUnitTestCase(test.NoDBTestCase):
|
|||
'delete_on_termination': True,
|
||||
'connection_info': '{"foo": "bar"}'})
|
||||
comp_ret = {'save_volume_id': old_volume_id}
|
||||
new_info = {"foo": "bar"}
|
||||
new_info = {"foo": "bar", "serial": old_volume_id}
|
||||
swap_volume_mock.return_value = (comp_ret, new_info)
|
||||
volume_connector_mock.return_value = {}
|
||||
update_bdm_mock.return_value = fake_bdm
|
||||
|
@ -1953,7 +1953,7 @@ class ComputeManagerUnitTestCase(test.NoDBTestCase):
|
|||
fake_instance.fake_instance_obj(self.context,
|
||||
**{'uuid': uuids.instance}))
|
||||
update_values = {'no_device': False,
|
||||
'connection_info': u'{"foo": "bar"}',
|
||||
'connection_info': jsonutils.dumps(new_info),
|
||||
'volume_id': old_volume_id,
|
||||
'source_type': u'volume',
|
||||
'snapshot_id': None,
|
||||
|
|
|
@ -14735,18 +14735,12 @@ class LibvirtConnTestCase(test.NoDBTestCase):
|
|||
|
||||
@mock.patch('nova.virt.libvirt.driver.LibvirtDriver._disconnect_volume')
|
||||
@mock.patch('nova.virt.libvirt.driver.LibvirtDriver._swap_volume')
|
||||
@mock.patch('nova.objects.block_device.BlockDeviceMapping.'
|
||||
'get_by_volume_and_instance')
|
||||
@mock.patch('nova.virt.libvirt.driver.LibvirtDriver._get_volume_config')
|
||||
@mock.patch('nova.virt.libvirt.driver.LibvirtDriver._connect_volume')
|
||||
@mock.patch('nova.virt.libvirt.host.Host.get_guest')
|
||||
def _test_swap_volume_driver_bdm_save(self, get_guest,
|
||||
connect_volume, get_volume_config,
|
||||
get_by_volume_and_instance,
|
||||
swap_volume,
|
||||
disconnect_volume,
|
||||
volume_save,
|
||||
source_type):
|
||||
def _test_swap_volume_driver(self, get_guest, connect_volume,
|
||||
get_volume_config, swap_volume,
|
||||
disconnect_volume, source_type):
|
||||
conn = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI())
|
||||
instance = objects.Instance(**self.test_instance)
|
||||
old_connection_info = {'driver_volume_type': 'fake',
|
||||
|
@ -14775,16 +14769,6 @@ class LibvirtConnTestCase(test.NoDBTestCase):
|
|||
get_volume_config.return_value = mock.MagicMock(
|
||||
source_path='/fake-new-volume')
|
||||
|
||||
bdm = objects.BlockDeviceMapping(self.context,
|
||||
**fake_block_device.FakeDbBlockDeviceDict(
|
||||
{'id': 2, 'instance_uuid': uuids.instance,
|
||||
'device_name': '/dev/vdb',
|
||||
'source_type': source_type,
|
||||
'destination_type': 'volume',
|
||||
'volume_id': 'fake-volume-id-2',
|
||||
'boot_index': 0}))
|
||||
get_by_volume_and_instance.return_value = bdm
|
||||
|
||||
conn.swap_volume(old_connection_info, new_connection_info, instance,
|
||||
'/dev/vdb', 1)
|
||||
|
||||
|
@ -14794,22 +14778,15 @@ class LibvirtConnTestCase(test.NoDBTestCase):
|
|||
swap_volume.assert_called_once_with(guest, 'vdb',
|
||||
'/fake-new-volume', 1)
|
||||
disconnect_volume.assert_called_once_with(old_connection_info, 'vdb')
|
||||
volume_save.assert_called_once_with()
|
||||
|
||||
@mock.patch('nova.virt.block_device.DriverVolumeBlockDevice.save')
|
||||
def test_swap_volume_driver_bdm_save_source_is_volume(self, volume_save):
|
||||
self._test_swap_volume_driver_bdm_save(volume_save=volume_save,
|
||||
source_type='volume')
|
||||
def test_swap_volume_driver_source_is_volume(self):
|
||||
self._test_swap_volume_driver(source_type='volume')
|
||||
|
||||
@mock.patch('nova.virt.block_device.DriverImageBlockDevice.save')
|
||||
def test_swap_volume_driver_bdm_save_source_is_image(self, volume_save):
|
||||
self._test_swap_volume_driver_bdm_save(volume_save=volume_save,
|
||||
source_type='image')
|
||||
def test_swap_volume_driver_source_is_image(self):
|
||||
self._test_swap_volume_driver(source_type='image')
|
||||
|
||||
@mock.patch('nova.virt.block_device.DriverSnapshotBlockDevice.save')
|
||||
def test_swap_volume_driver_bdm_save_source_is_snapshot(self, volume_save):
|
||||
self._test_swap_volume_driver_bdm_save(volume_save=volume_save,
|
||||
source_type='snapshot')
|
||||
def test_swap_volume_driver_source_is_snapshot(self):
|
||||
self._test_swap_volume_driver(source_type='snapshot')
|
||||
|
||||
@mock.patch('nova.virt.libvirt.guest.BlockDevice.is_job_complete')
|
||||
def _test_live_snapshot(self, mock_is_job_complete,
|
||||
|
|
|
@ -1286,20 +1286,19 @@ class LibvirtDriver(driver.ComputeDriver):
|
|||
CONF.libvirt.virt_type, disk_dev),
|
||||
'type': 'disk',
|
||||
}
|
||||
# NOTE (lyarwood): new_connection_info will be modified by the
|
||||
# following _connect_volume call down into the volume drivers. The
|
||||
# majority of the volume drivers will add a device_path that is in turn
|
||||
# used by _get_volume_config to set the source_path of the
|
||||
# LibvirtConfigGuestDisk object it returns. We do not explicitly save
|
||||
# this to the BDM here as the upper compute swap_volume method will
|
||||
# eventually do this for us.
|
||||
self._connect_volume(new_connection_info, disk_info)
|
||||
conf = self._get_volume_config(new_connection_info, disk_info)
|
||||
if not conf.source_path:
|
||||
self._disconnect_volume(new_connection_info, disk_dev)
|
||||
raise NotImplementedError(_("Swap only supports host devices"))
|
||||
|
||||
# Save updates made in connection_info when connect_volume was called
|
||||
volume_id = new_connection_info.get('serial')
|
||||
bdm = objects.BlockDeviceMapping.get_by_volume_and_instance(
|
||||
nova_context.get_admin_context(), volume_id, instance.uuid)
|
||||
driver_bdm = driver_block_device.convert_volume(bdm)
|
||||
driver_bdm['connection_info'] = new_connection_info
|
||||
driver_bdm.save()
|
||||
|
||||
self._swap_volume(guest, disk_dev, conf.source_path, resize_to)
|
||||
self._disconnect_volume(old_connection_info, disk_dev)
|
||||
|
||||
|
|
Loading…
Reference in New Issue