diff --git a/api-ref/source/parameters.yaml b/api-ref/source/parameters.yaml index e0a8eeba40..bc828c85f0 100644 --- a/api-ref/source/parameters.yaml +++ b/api-ref/source/parameters.yaml @@ -2648,6 +2648,7 @@ event_name: - ``network-vif-deleted`` - ``volume-extended`` (since microversion ``2.51``) - ``power-update`` (since microversion ``2.76``) + - ``accelerator-request-bound`` (since microversion ``2.82``) in: body required: true @@ -2685,6 +2686,8 @@ event_tag: A string value that identifies the event. Certain types of events require specific tags: + - For the ``accelerator-request-bound`` event, the tag must be + the accelerator request UUID. - For the ``power-update`` event the tag must be either be ``POWER_ON`` or ``POWER_OFF``. - For the ``volume-extended`` event the tag must be the volume id. diff --git a/doc/api_samples/versions/v21-version-get-resp.json b/doc/api_samples/versions/v21-version-get-resp.json index 3877e25f57..395eca072e 100644 --- a/doc/api_samples/versions/v21-version-get-resp.json +++ b/doc/api_samples/versions/v21-version-get-resp.json @@ -19,7 +19,7 @@ } ], "status": "CURRENT", - "version": "2.81", + "version": "2.82", "min_version": "2.1", "updated": "2013-07-23T11:33:21Z" } diff --git a/doc/api_samples/versions/versions-get-resp.json b/doc/api_samples/versions/versions-get-resp.json index 6edc435a0e..874f5a4afe 100644 --- a/doc/api_samples/versions/versions-get-resp.json +++ b/doc/api_samples/versions/versions-get-resp.json @@ -22,7 +22,7 @@ } ], "status": "CURRENT", - "version": "2.81", + "version": "2.82", "min_version": "2.1", "updated": "2013-07-23T11:33:21Z" } diff --git a/nova/api/openstack/api_version_request.py b/nova/api/openstack/api_version_request.py index 6c99006779..0ca661d66c 100644 --- a/nova/api/openstack/api_version_request.py +++ b/nova/api/openstack/api_version_request.py @@ -220,6 +220,10 @@ REST_API_VERSION_HISTORY = """REST API Version History: ``GET /servers/{server_id}/migrations/{migration_id}``. * 2.81 - Adds support for image cache management by aggregate by adding ``POST /os-aggregates/{aggregate_id}/images``. + * 2.82 - Adds ``accelerator-request-bound`` event to + ``os-server-external-events`` API. This event is sent by Cyborg + to indicate completion of ARQ binding. The ARQs can be obtained + from Cyborg with ``GET /v2/accelerator_requests?instance={uuid}`` """ # The minimum and maximum versions of the API supported @@ -228,7 +232,7 @@ REST_API_VERSION_HISTORY = """REST API Version History: # Note(cyeoh): This only applies for the v2.1 API once microversions # support is fully merged. It does not affect the V2 API. _MIN_API_VERSION = "2.1" -_MAX_API_VERSION = "2.81" +_MAX_API_VERSION = "2.82" DEFAULT_API_VERSION = _MIN_API_VERSION # Almost all proxy APIs which are related to network, images and baremetal diff --git a/nova/api/openstack/compute/rest_api_version_history.rst b/nova/api/openstack/compute/rest_api_version_history.rst index ecb82de0a0..44cd73e659 100644 --- a/nova/api/openstack/compute/rest_api_version_history.rst +++ b/nova/api/openstack/compute/rest_api_version_history.rst @@ -1080,3 +1080,10 @@ project, for example: Adds support for image cache management by aggregate by adding ``POST /os-aggregates/{aggregate_id}/images``. + +2.82 +---- + +Adds ``accelerator-request-bound`` event to ``os-server-external-events`` +API. This event is sent by Cyborg to indicate completion of the binding +event for one accelerator request (ARQ) associated with an instance. diff --git a/nova/api/openstack/compute/schemas/server_external_events.py b/nova/api/openstack/compute/schemas/server_external_events.py index ff02a08430..b8a89e047d 100644 --- a/nova/api/openstack/compute/schemas/server_external_events.py +++ b/nova/api/openstack/compute/schemas/server_external_events.py @@ -59,3 +59,7 @@ name['enum'].append('volume-extended') create_v276 = copy.deepcopy(create_v251) name = create_v276['properties']['events']['items']['properties']['name'] name['enum'].append('power-update') + +create_v282 = copy.deepcopy(create_v276) +name = create_v282['properties']['events']['items']['properties']['name'] +name['enum'].append('accelerator-request-bound') diff --git a/nova/api/openstack/compute/server_external_events.py b/nova/api/openstack/compute/server_external_events.py index 35f394f41c..e14b23af2e 100644 --- a/nova/api/openstack/compute/server_external_events.py +++ b/nova/api/openstack/compute/server_external_events.py @@ -26,7 +26,8 @@ from nova.policies import server_external_events as see_policies LOG = logging.getLogger(__name__) -TAG_REQUIRED = ('volume-extended', 'power-update') +TAG_REQUIRED = ('volume-extended', 'power-update', + 'accelerator-request-bound') class ServerExternalEventsController(wsgi.Controller): @@ -67,7 +68,8 @@ class ServerExternalEventsController(wsgi.Controller): @wsgi.response(200) @validation.schema(server_external_events.create, '2.0', '2.50') @validation.schema(server_external_events.create_v251, '2.51', '2.75') - @validation.schema(server_external_events.create_v276, '2.76') + @validation.schema(server_external_events.create_v276, '2.76', '2.81') + @validation.schema(server_external_events.create_v282, '2.82') def create(self, req, body): """Creates a new instance event.""" context = req.environ['nova.context'] diff --git a/nova/objects/external_event.py b/nova/objects/external_event.py index e2c7e95b11..b1acfc4aa0 100644 --- a/nova/objects/external_event.py +++ b/nova/objects/external_event.py @@ -29,6 +29,10 @@ EVENT_NAMES = [ # Power state has changed for this instance 'power-update', + + # Accelerator Request got bound, tag is ARQ uuid. + # Sent when an ARQ for an instance has been bound or failed to bind. + 'accelerator-request-bound', ] EVENT_STATUSES = ['failed', 'completed', 'in-progress'] @@ -45,7 +49,8 @@ class InstanceExternalEvent(obj_base.NovaObject): # Version 1.1: adds network-vif-deleted event # Version 1.2: adds volume-extended event # Version 1.3: adds power-update event - VERSION = '1.3' + # Version 1.4: adds accelerator-request-bound event + VERSION = '1.4' fields = { 'instance_uuid': fields.UUIDField(), diff --git a/nova/tests/unit/api/openstack/compute/test_server_external_events.py b/nova/tests/unit/api/openstack/compute/test_server_external_events.py index 7d0d6e1865..ce042b5442 100644 --- a/nova/tests/unit/api/openstack/compute/test_server_external_events.py +++ b/nova/tests/unit/api/openstack/compute/test_server_external_events.py @@ -262,3 +262,34 @@ class ServerExternalEventsTestV276(ServerExternalEventsTestV21): body=body) self.assertIn('Invalid input for field/attribute name.', six.text_type(exp)) + + +@mock.patch('nova.objects.InstanceMappingList.get_by_instance_uuids', + fake_get_by_instance_uuids) +@mock.patch('nova.objects.InstanceList.get_by_filters', + fake_get_by_filters) +class ServerExternalEventsTestV282(ServerExternalEventsTestV21): + wsgi_api_version = '2.82' + + def setUp(self): + super(ServerExternalEventsTestV282, self).setUp() + self.useFixture(fx.EnvironmentVariable('OS_DEBUG', '1')) + self.stdlog = self.useFixture(fixtures.StandardLogging()) + + def test_accelerator_request_bound_event(self): + body = self.default_body + event_name = 'accelerator-request-bound' + body['events'][0]['name'] = event_name # event 0 has a tag + body['events'][1]['name'] = event_name # event 1 has no tag + + result, code = self._assert_call( + body, [fake_instance_uuids[0]], [event_name]) + + self.assertEqual(200, result['events'][0]['code']) + self.assertEqual('completed', result['events'][0]['status']) + + msg = "Event tag is missing for instance" + self.assertIn(msg, self.stdlog.logger.output) + self.assertEqual(400, result['events'][1]['code']) + self.assertEqual('failed', result['events'][1]['status']) + self.assertEqual(207, code) diff --git a/nova/tests/unit/objects/test_objects.py b/nova/tests/unit/objects/test_objects.py index d0191e0ffd..ce636e67be 100644 --- a/nova/tests/unit/objects/test_objects.py +++ b/nova/tests/unit/objects/test_objects.py @@ -1075,7 +1075,7 @@ object_data = { 'InstanceActionEventList': '1.1-13d92fb953030cdbfee56481756e02be', 'InstanceActionList': '1.1-a2b2fb6006b47c27076d3a1d48baa759', 'InstanceDeviceMetadata': '1.0-74d78dd36aa32d26d2769a1b57caf186', - 'InstanceExternalEvent': '1.3-e47782874cca95bb96e566286e9d1e23', + 'InstanceExternalEvent': '1.4-06c2dfcf2d2813c24cd37ee728524f1a', 'InstanceFault': '1.2-7ef01f16f1084ad1304a513d6d410a38', 'InstanceFaultList': '1.2-6bb72de2872fe49ded5eb937a93f2451', 'InstanceGroup': '1.11-852ac511d30913ee88f3c3a869a8f30a', diff --git a/releasenotes/notes/accelerator-requests-6c9a6fef77ab776a.yaml b/releasenotes/notes/accelerator-requests-6c9a6fef77ab776a.yaml new file mode 100644 index 0000000000..6c8598ff03 --- /dev/null +++ b/releasenotes/notes/accelerator-requests-6c9a6fef77ab776a.yaml @@ -0,0 +1,10 @@ +--- +features: + - | + Handling accelerator requests for an instance is now supported (where + supported by the underlying virt driver) as of microversion + 2.82. The Cyborg service generates an event for the binding + completion for each accelerator request for an instance. + Adds a new event ``accelerator_request_bound`` for this to the API: + + * ``POST /os-server-external-events``