Pass accelerator requests to each virt driver from compute manager.

Update the signature of the spawn() API for each virt driver
to include accel_info, which is a list of accelerator requests.

Change-Id: I4aac66c125a162bf35991a7d0c2638c7475ec0e7
Blueprint: nova-cyborg-interaction
This commit is contained in:
Sundar Nadathur 2019-12-10 20:58:26 -08:00
parent cc630b4eb6
commit 1ff60fa52d
11 changed files with 75 additions and 16 deletions

View File

@ -2363,13 +2363,15 @@ class ComputeManager(manager.Manager):
task_states.BLOCK_DEVICE_MAPPING)
block_device_info = resources['block_device_info']
network_info = resources['network_info']
accel_info = resources['accel_info']
LOG.debug('Start spawning the instance on the hypervisor.',
instance=instance)
with timeutils.StopWatch() as timer:
self.driver.spawn(context, instance, image_meta,
injected_files, admin_password,
allocs, network_info=network_info,
block_device_info=block_device_info)
block_device_info=block_device_info,
accel_info=accel_info)
LOG.info('Took %0.2f seconds to spawn the instance on '
'the hypervisor.', timer.elapsed(),
instance=instance)

View File

@ -6175,6 +6175,46 @@ class ComputeManagerBuildInstanceTestCase(test.NoDBTestCase):
mock.call(self.instance.uuid),
mock.call(self.instance.uuid, only_resolved=True)])
@mock.patch.object(fake_driver.FakeDriver, 'spawn')
@mock.patch('nova.objects.Instance.save')
@mock.patch('nova.scheduler.client.report.SchedulerReportClient.'
'get_allocations_for_consumer')
@mock.patch.object(manager.ComputeManager, '_get_request_group_mapping')
@mock.patch.object(manager.ComputeManager, '_check_trusted_certs')
@mock.patch.object(manager.ComputeManager, '_check_device_tagging')
@mock.patch.object(compute_utils, 'notify_about_instance_create')
@mock.patch.object(manager.ComputeManager, '_notify_about_instance_usage')
def test_spawn_called_with_accel_info(self, mock_ins_usage,
mock_ins_create, mock_dev_tag, mock_certs, mock_req_group_map,
mock_get_allocations, mock_ins_save, mock_spawn):
accel_info = [{'k1': 'v1', 'k2': 'v2'}]
@contextlib.contextmanager
def fake_build_resources(compute_mgr, *args, **kwargs):
yield {
'block_device_info': None,
'network_info': None,
'accel_info': accel_info,
}
self.stub_out('nova.compute.manager.ComputeManager._build_resources',
fake_build_resources)
mock_req_group_map.return_value = None
mock_get_allocations.return_value = mock.sentinel.allocation
self.compute._build_and_run_instance(self.context, self.instance,
self.image, injected_files=self.injected_files,
admin_password=self.admin_pass,
requested_networks=self.requested_networks,
security_groups=self.security_groups,
block_device_mapping=self.block_device_mapping,
node=self.node, limits=self.limits,
filter_properties=self.filter_properties)
mock_spawn.assert_called_once_with(self.context, self.instance,
mock.ANY, self.injected_files, self.admin_pass, mock.ANY,
network_info=None, block_device_info=None, accel_info=accel_info)
def test_build_and_run_instance_called_with_proper_args(self):
self._test_build_and_run_instance()
@ -6373,7 +6413,7 @@ class ComputeManagerBuildInstanceTestCase(test.NoDBTestCase):
mock_spawn.assert_called_once_with(self.context, self.instance,
test.MatchType(objects.ImageMeta), self.injected_files,
self.admin_pass, self.allocations, network_info=self.network_info,
block_device_info=self.block_device_info)
block_device_info=self.block_device_info, accel_info=[])
@mock.patch.object(manager.ComputeManager, '_build_and_run_instance')
@mock.patch.object(conductor_api.ComputeTaskAPI, 'build_instances')
@ -6864,7 +6904,7 @@ class ComputeManagerBuildInstanceTestCase(test.NoDBTestCase):
self.context, self.instance, test.MatchType(objects.ImageMeta),
self.injected_files, self.admin_pass, self.allocations,
network_info=self.network_info,
block_device_info=self.block_device_info)
block_device_info=self.block_device_info, accel_info=[])
def test_instance_not_found(self):
got_exc = exception.InstanceNotFound(instance_id=1)
@ -6999,7 +7039,7 @@ class ComputeManagerBuildInstanceTestCase(test.NoDBTestCase):
test.MatchType(objects.ImageMeta),
self.injected_files, self.admin_pass, self.allocations,
network_info=self.network_info,
block_device_info=self.block_device_info)])
block_device_info=self.block_device_info, accel_info=[])])
_shutdown_instance.assert_called_once_with(self.context,
self.instance, self.block_device_mapping,

View File

@ -349,7 +349,7 @@ class ComputeDriver(object):
def spawn(self, context, instance, image_meta, injected_files,
admin_password, allocations, network_info=None,
block_device_info=None, power_on=True):
block_device_info=None, power_on=True, accel_info=None):
"""Create a new instance/VM/domain on the virtualization platform.
Once this successfully completes, the instance should be
@ -376,6 +376,22 @@ class ComputeDriver(object):
attached to the instance.
:param power_on: True if the instance should be powered on, False
otherwise
:param arqs: List of bound accelerator requests for this instance.
[
{'uuid': $arq_uuid,
'device_profile_name': $dp_name,
'device_profile_group_id': $dp_request_group_index,
'state': 'Bound',
'device_rp_uuid': $resource_provider_uuid,
'hostname': $host_nodename,
'instance_uuid': $instance_uuid,
'attach_handle_info': { # PCI bdf
'bus': '0c', 'device': '0', 'domain': '0000', 'function': '0'},
'attach_handle_type': 'PCI'
# or 'TEST_PCI' for Cyborg fake driver
}
]
Also doc'd in nova/accelerator/cyborg.py::get_arqs_for_instance()
"""
raise NotImplementedError()

View File

@ -181,7 +181,7 @@ class FakeDriver(driver.ComputeDriver):
def spawn(self, context, instance, image_meta, injected_files,
admin_password, allocations, network_info=None,
block_device_info=None, power_on=True):
block_device_info=None, power_on=True, accel_info=None):
if network_info:
for vif in network_info:
@ -784,7 +784,7 @@ class FakeRescheduleDriver(FakeDriver):
def spawn(self, context, instance, image_meta, injected_files,
admin_password, allocations, network_info=None,
block_device_info=None, power_on=True):
block_device_info=None, power_on=True, accel_info=None):
if not self.rescheduled.get(instance.uuid, False):
# We only reschedule on the first time something hits spawn().
self.rescheduled[instance.uuid] = True
@ -807,7 +807,7 @@ class FakeBuildAbortDriver(FakeDriver):
"""
def spawn(self, context, instance, image_meta, injected_files,
admin_password, allocations, network_info=None,
block_device_info=None, power_on=True):
block_device_info=None, power_on=True, accel_info=None):
raise exception.BuildAbortException(
instance_uuid=instance.uuid, reason='FakeBuildAbortDriver')
@ -823,7 +823,7 @@ class FakeUnshelveSpawnFailDriver(FakeDriver):
"""
def spawn(self, context, instance, image_meta, injected_files,
admin_password, allocations, network_info=None,
block_device_info=None, power_on=True):
block_device_info=None, power_on=True, accel_info=None):
if instance.vm_state == vm_states.SHELVED_OFFLOADED:
raise exception.VirtualInterfaceCreateException(
'FakeUnshelveSpawnFailDriver')

View File

@ -160,7 +160,7 @@ class HyperVDriver(driver.ComputeDriver):
def spawn(self, context, instance, image_meta, injected_files,
admin_password, allocations, network_info=None,
block_device_info=None, power_on=True):
block_device_info=None, power_on=True, accel_info=None):
self._vmops.spawn(context, instance, image_meta, injected_files,
admin_password, network_info, block_device_info)

View File

@ -1141,7 +1141,7 @@ class IronicDriver(virt_driver.ComputeDriver):
def spawn(self, context, instance, image_meta, injected_files,
admin_password, allocations, network_info=None,
block_device_info=None, power_on=True):
block_device_info=None, power_on=True, accel_info=None):
"""Deploy an instance.
:param context: The security context.
@ -1158,6 +1158,7 @@ class IronicDriver(virt_driver.ComputeDriver):
:param network_info: Instance network information.
:param block_device_info: Instance block device
information.
:param arqs: Accelerator requests for this instance.
:param power_on: True if the instance should be powered on, False
otherwise
"""

View File

@ -3457,7 +3457,7 @@ class LibvirtDriver(driver.ComputeDriver):
def spawn(self, context, instance, image_meta, injected_files,
admin_password, allocations, network_info=None,
block_device_info=None, power_on=True):
block_device_info=None, power_on=True, accel_info=None):
disk_info = blockinfo.get_disk_info(CONF.libvirt.virt_type,
instance,
image_meta,

View File

@ -240,7 +240,7 @@ class PowerVMDriver(driver.ComputeDriver):
def spawn(self, context, instance, image_meta, injected_files,
admin_password, allocations, network_info=None,
block_device_info=None, power_on=True):
block_device_info=None, power_on=True, accel_info=None):
"""Create a new instance/VM/domain on the virtualization platform.
Once this successfully completes, the instance should be

View File

@ -540,7 +540,7 @@ class VMwareVCDriver(driver.ComputeDriver):
def spawn(self, context, instance, image_meta, injected_files,
admin_password, allocations, network_info=None,
block_device_info=None, power_on=True):
block_device_info=None, power_on=True, accel_info=None):
"""Create VM instance."""
self._vmops.spawn(context, instance, image_meta, injected_files,
admin_password, network_info, block_device_info)

View File

@ -215,7 +215,7 @@ class XenAPIDriver(driver.ComputeDriver):
def spawn(self, context, instance, image_meta, injected_files,
admin_password, allocations, network_info=None,
block_device_info=None, power_on=True):
block_device_info=None, power_on=True, accel_info=None):
"""Create VM instance."""
vgpu_info = self._get_vgpu_info(allocations)
self._vmops.spawn(context, instance, image_meta, injected_files,

View File

@ -144,7 +144,7 @@ class ZVMDriver(driver.ComputeDriver):
def spawn(self, context, instance, image_meta, injected_files,
admin_password, allocations, network_info=None,
block_device_info=None, power_on=True):
block_device_info=None, power_on=True, accel_info=None):
LOG.info("Spawning new instance %s on zVM hypervisor",
instance.name, instance=instance)