Pass allocations to virt drivers when resizing

Some features like vGPUs require to have allocations to be checked locally
by the virt driver but resize (and cold migrate) was not passing them.

This change just gives the allocations to the target node when the resize
is done by adding the allocations to the finish_migration() interface.

Related-Bug: #1778563
Change-Id: Ifd76289964d513e9544544e5787f5f8999589475
This commit is contained in:
Sylvain Bauza 2018-06-29 11:33:10 +02:00
parent b6f3d393aa
commit 580eedbe2d
12 changed files with 48 additions and 23 deletions

View File

@ -5779,11 +5779,19 @@ class ComputeManager(manager.Manager):
# automatically power on the instance after it's migrated
power_on = old_vm_state != vm_states.STOPPED
# NOTE(sbauza): During a migration, the original allocation is against
# the migration UUID while the target allocation (for the destination
# node) is related to the instance UUID, so here we need to pass the
# new ones.
allocations = self.reportclient.get_allocs_for_consumer(
context, instance.uuid)['allocations']
try:
self.driver.finish_migration(context, migration, instance,
disk_info,
network_info,
image_meta, resize_instance,
allocations,
block_device_info, power_on)
except Exception:
# Note that we do not rollback port bindings to the source host

View File

@ -250,11 +250,17 @@ class BaseTestCase(test.TestCase):
# Just to make long lines short
self.rt = self.compute.rt
self.mock_get_allocs = self.useFixture(
self.mock_get_allocations = self.useFixture(
fixtures.fixtures.MockPatch(
'nova.scheduler.client.report.SchedulerReportClient.'
'get_allocations_for_consumer')).mock
self.mock_get_allocs.return_value = {}
self.mock_get_allocations.return_value = {}
self.mock_get_allocs = self.useFixture(
fixtures.fixtures.MockPatch(
'nova.scheduler.client.report.SchedulerReportClient.'
'get_allocs_for_consumer')).mock
self.mock_get_allocs.return_value = {'allocations': {}}
def tearDown(self):
ctxt = context.get_admin_context()
@ -4928,7 +4934,7 @@ class ComputeTestCase(BaseTestCase,
# which makes this a resize
mock_virt_mig.assert_called_once_with(self.context, migration,
instance, disk_info, 'fake-nwinfo1',
test.MatchType(objects.ImageMeta), resize_instance,
test.MatchType(objects.ImageMeta), resize_instance, mock.ANY,
'fake-bdminfo', power_on)
mock_get_blk.assert_called_once_with(self.context, instance,
refresh_conn_info=True,
@ -4943,6 +4949,8 @@ class ComputeTestCase(BaseTestCase,
mock_get_vol_connector.return_value, '/dev/vdb')
mock_attachment_complete.assert_called_once_with(
self.context, uuids.attachment_id)
self.mock_get_allocs.assert_called_once_with(self.context,
instance.uuid)
def test_finish_resize_from_active(self):
self._test_finish_resize(power_on=True)
@ -12763,7 +12771,8 @@ class EvacuateHostTestCase(BaseTestCase):
mock_setup_instance_network_on_host.assert_called_once_with(
ctxt, self.inst, self.inst.host, migration,
provider_mappings=mock.sentinel.mapping)
self.mock_get_allocs.assert_called_once_with(ctxt, self.inst.uuid)
self.mock_get_allocations.assert_called_once_with(ctxt,
self.inst.uuid)
mock_update_pci_req.assert_called_once_with(
ctxt, self.compute.reportclient, self.inst,
@ -13109,8 +13118,8 @@ class ComputeInjectedFilesTestCase(BaseTestCase):
admin_password, allocations, nw_info, block_device_info,
db_api=None):
self.assertEqual(self.expected, injected_files)
self.assertEqual(self.mock_get_allocs.return_value, allocations)
self.mock_get_allocs.assert_called_once_with(instance.uuid)
self.assertEqual(self.mock_get_allocations.return_value, allocations)
self.mock_get_allocations.assert_called_once_with(instance.uuid)
def _test(self, injected_files, decoded_files):
self.expected = decoded_files

View File

@ -367,8 +367,8 @@ class ShelveComputeManagerTestCase(test_compute.BaseTestCase):
test.MatchType(objects.ImageMeta), injected_files=[],
admin_password=None, allocations={}, network_info=[],
block_device_info='fake_bdm')
self.mock_get_allocs.assert_called_once_with(self.context,
instance.uuid)
self.mock_get_allocations.assert_called_once_with(self.context,
instance.uuid)
mock_get_power_state.assert_called_once_with(self.context, instance)
self.assertNotIn('shelved_at', instance.system_metadata)
@ -470,8 +470,8 @@ class ShelveComputeManagerTestCase(test_compute.BaseTestCase):
test.MatchType(objects.ImageMeta),
injected_files=[], admin_password=None,
allocations={}, network_info=[], block_device_info='fake_bdm')
self.mock_get_allocs.assert_called_once_with(self.context,
instance.uuid)
self.mock_get_allocations.assert_called_once_with(self.context,
instance.uuid)
mock_get_power_state.assert_called_once_with(self.context, instance)
@mock.patch('nova.objects.BlockDeviceMappingList.get_by_instance_uuid')

View File

@ -428,7 +428,8 @@ class HyperVDriverTestCase(test_base.HyperVBaseTestCase):
mock.sentinel.context, mock.sentinel.migration,
mock.sentinel.instance, mock.sentinel.disk_info,
mock.sentinel.network_info, mock.sentinel.image_meta,
mock.sentinel.resize_instance, mock.sentinel.block_device_info,
mock.sentinel.resize_instance, mock.sentinel.allocations,
mock.sentinel.block_device_info,
mock.sentinel.power_on)
self.driver._migrationops.finish_migration.assert_called_once_with(

View File

@ -21443,7 +21443,7 @@ class LibvirtDriverTestCase(test.NoDBTestCase, TraitsComparisonMixin):
self.drvr.finish_migration(
context.get_admin_context(), migration, instance,
disk_info_text, [], image_meta,
resize_instance, bdi, power_on)
resize_instance, mock.ANY, bdi, power_on)
# Assert that we converted the root, ephemeral, and swap disks
instance_path = libvirt_utils.get_instance_path(instance)

View File

@ -1852,7 +1852,8 @@ class XenAPIMigrateInstance(stubs.XenAPITestBase):
conn.finish_migration(self.context, self.migration, instance,
dict(base_copy=base_uuid, cow=cow_uuid),
network_info, image_meta, resize_instance=True,
block_device_info=None, power_on=power_on)
allocations={}, block_device_info=None,
power_on=power_on)
self.assertTrue(self.called)
self.assertEqual(self.fake_vm_start_called, power_on)
@ -1893,7 +1894,8 @@ class XenAPIMigrateInstance(stubs.XenAPITestBase):
conn.finish_migration(self.context, self.migration, instance,
dict(base_copy='hurr', cow='durr'),
network_info, image_meta, resize_instance=True,
block_device_info=None, power_on=power_on)
allocations={}, block_device_info=None,
power_on=power_on)
self.assertTrue(self.called)
self.assertEqual(self.fake_vm_start_called, power_on)
@ -1923,7 +1925,8 @@ class XenAPIMigrateInstance(stubs.XenAPITestBase):
{'id': instance['image_ref'], 'disk_format': 'vhd'})
conn.finish_migration(self.context, self.migration, instance,
dict(base_copy='hurr', cow='durr'),
network_info, image_meta, resize_instance=True)
network_info, image_meta, resize_instance=True,
allocations={})
def test_finish_migrate_no_resize_vdi(self):
instance = create_instance_with_system_metadata(self.context,
@ -1942,7 +1945,8 @@ class XenAPIMigrateInstance(stubs.XenAPITestBase):
{'id': instance['image_ref'], 'disk_format': 'vhd'})
conn.finish_migration(self.context, self.migration, instance,
dict(base_copy='hurr', cow='durr'),
network_info, image_meta, resize_instance=False)
network_info, image_meta, resize_instance=False,
allocations={})
@stub_vm_utils_with_vdi_attached
def test_migrate_too_many_partitions_no_resize_down(self):

View File

@ -730,7 +730,7 @@ class ComputeDriver(object):
def finish_migration(self, context, migration, instance, disk_info,
network_info, image_meta, resize_instance,
block_device_info=None, power_on=True):
allocations, block_device_info=None, power_on=True):
"""Completes a resize/migration.
:param context: the context for the migration/resize
@ -742,6 +742,9 @@ class ComputeDriver(object):
The metadata of the image of the instance.
:param resize_instance: True if the instance is being resized,
False otherwise
:param allocations: Information about resources allocated to the
instance via placement, of the form returned by
SchedulerReportClient.get_allocs_for_consumer.
:param block_device_info: instance volume block device info
:param power_on: True if the instance should be powered on, False
otherwise

View File

@ -601,8 +601,8 @@ class FakeDriver(driver.ComputeDriver):
def finish_migration(self, context, migration, instance, disk_info,
network_info, image_meta, resize_instance,
block_device_info=None, power_on=True):
injected_files = admin_password = allocations = None
allocations, block_device_info=None, power_on=True):
injected_files = admin_password = None
# Finish migration is just like spawning the guest on a destination
# host during resize/cold migrate, so re-use the spawn() fake to
# claim resources and track the instance on this "hypervisor".

View File

@ -326,7 +326,7 @@ class HyperVDriver(driver.ComputeDriver):
def finish_migration(self, context, migration, instance, disk_info,
network_info, image_meta, resize_instance,
block_device_info=None, power_on=True):
allocations, block_device_info=None, power_on=True):
self._migrationops.finish_migration(context, migration, instance,
disk_info, network_info,
image_meta, resize_instance,

View File

@ -10039,7 +10039,7 @@ class LibvirtDriver(driver.ComputeDriver):
def finish_migration(self, context, migration, instance, disk_info,
network_info, image_meta, resize_instance,
block_device_info=None, power_on=True):
allocations, block_device_info=None, power_on=True):
LOG.debug("Starting finish_migration", instance=instance)
block_disk_info = blockinfo.get_disk_info(CONF.libvirt.virt_type,

View File

@ -287,7 +287,7 @@ class VMwareVCDriver(driver.ComputeDriver):
def finish_migration(self, context, migration, instance, disk_info,
network_info, image_meta, resize_instance,
block_device_info=None, power_on=True):
allocations, block_device_info=None, power_on=True):
"""Completes a resize, turning on the migrated instance."""
self._vmops.finish_migration(context, migration, instance, disk_info,
network_info, image_meta, resize_instance,

View File

@ -238,7 +238,7 @@ class XenAPIDriver(driver.ComputeDriver):
def finish_migration(self, context, migration, instance, disk_info,
network_info, image_meta, resize_instance,
block_device_info=None, power_on=True):
allocations, block_device_info=None, power_on=True):
"""Completes a resize, turning on the migrated instance."""
self._vmops.finish_migration(context, migration, instance, disk_info,
network_info, image_meta, resize_instance,