diff --git a/nova/compute/manager.py b/nova/compute/manager.py index c2d4a9b21e86..369906400539 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -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) diff --git a/nova/tests/unit/compute/test_compute_mgr.py b/nova/tests/unit/compute/test_compute_mgr.py index 2a8a2cbe1fce..33623f5175e6 100644 --- a/nova/tests/unit/compute/test_compute_mgr.py +++ b/nova/tests/unit/compute/test_compute_mgr.py @@ -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, diff --git a/nova/virt/driver.py b/nova/virt/driver.py index 2251d596bc63..9f0bcb65bd4f 100644 --- a/nova/virt/driver.py +++ b/nova/virt/driver.py @@ -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() diff --git a/nova/virt/fake.py b/nova/virt/fake.py index e1a7dcd69df9..5f5c91c7d3c2 100644 --- a/nova/virt/fake.py +++ b/nova/virt/fake.py @@ -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') diff --git a/nova/virt/hyperv/driver.py b/nova/virt/hyperv/driver.py index 6385ad692c90..388ddf89b899 100644 --- a/nova/virt/hyperv/driver.py +++ b/nova/virt/hyperv/driver.py @@ -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) diff --git a/nova/virt/ironic/driver.py b/nova/virt/ironic/driver.py index 20ce154835dd..9409e4c97b6e 100644 --- a/nova/virt/ironic/driver.py +++ b/nova/virt/ironic/driver.py @@ -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 """ diff --git a/nova/virt/libvirt/driver.py b/nova/virt/libvirt/driver.py index 45af21c3bbef..30a7d495751a 100644 --- a/nova/virt/libvirt/driver.py +++ b/nova/virt/libvirt/driver.py @@ -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, diff --git a/nova/virt/powervm/driver.py b/nova/virt/powervm/driver.py index 0c08035d4e88..5e0b881f687b 100644 --- a/nova/virt/powervm/driver.py +++ b/nova/virt/powervm/driver.py @@ -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 diff --git a/nova/virt/vmwareapi/driver.py b/nova/virt/vmwareapi/driver.py index 1bfa337bf953..66cac7c03119 100644 --- a/nova/virt/vmwareapi/driver.py +++ b/nova/virt/vmwareapi/driver.py @@ -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) diff --git a/nova/virt/xenapi/driver.py b/nova/virt/xenapi/driver.py index c57052961e7e..e3952e142eba 100644 --- a/nova/virt/xenapi/driver.py +++ b/nova/virt/xenapi/driver.py @@ -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, diff --git a/nova/virt/zvm/driver.py b/nova/virt/zvm/driver.py index c7439333864a..a60e36ae6ba9 100644 --- a/nova/virt/zvm/driver.py +++ b/nova/virt/zvm/driver.py @@ -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)