Skip to content

Commit fb2ec18

Browse files
Balazs Gibizermriedem
authored andcommitted
allow getting resource request of every bound ports of an instance
This patch adds a new network api method get_requested_resource_for_instance() to query neutron about the resource needs of the ports currently bound to an instance. A later patch will use this to properly allocate resource for the ports during migration. blueprint: support-move-ops-with-qos-ports Change-Id: I56ea5ee94139dfa2cdf6bb76656bca2902e7ea9c
1 parent 2cf9a5f commit fb2ec18

File tree

3 files changed

+102
-0
lines changed

3 files changed

+102
-0
lines changed

nova/network/base_api.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,15 @@ def _get_instance_nw_info(self, context, instance, **kwargs):
258258
"""Template method, so a subclass can implement for neutron/network."""
259259
raise NotImplementedError()
260260

261+
def get_requested_resource_for_instance(self, context, instance_uuid):
262+
"""Collect resource requests from the ports associated to the instance
263+
264+
:param context: nova request context
265+
:param instance_uuid: The UUID of the instance
266+
:return: A list of RequestGroup objects
267+
"""
268+
raise NotImplementedError()
269+
261270
def validate_networks(self, context, requested_networks, num_instances):
262271
"""validate the networks passed at the time of creating
263272
the server.

nova/network/neutronv2/api.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2216,6 +2216,31 @@ def _ports_needed_per_instance(self, context, neutron, requested_networks):
22162216
raise exception.NetworkNotFound(network_id=id_str)
22172217
return ports_needed_per_instance
22182218

2219+
def get_requested_resource_for_instance(self, context, instance_uuid):
2220+
"""Collect resource requests from the ports associated to the instance
2221+
2222+
:param context: nova request context
2223+
:param instance_uuid: The UUID of the instance
2224+
:return: A list of RequestGroup objects
2225+
"""
2226+
2227+
neutron = get_client(context)
2228+
# get the ports associated to this instance
2229+
data = neutron.list_ports(
2230+
device_id=instance_uuid, fields=['id', 'resource_request'])
2231+
resource_requests = []
2232+
2233+
for port in data.get('ports', []):
2234+
if port.get('resource_request'):
2235+
# NOTE(gibi): explicitly orphan the RequestGroup by setting
2236+
# context=None as we never intended to save it to the DB.
2237+
resource_requests.append(
2238+
objects.RequestGroup.from_port_request(
2239+
context=None, port_uuid=port['id'],
2240+
port_resource_request=port['resource_request']))
2241+
2242+
return resource_requests
2243+
22192244
def validate_networks(self, context, requested_networks, num_instances):
22202245
"""Validate that the tenant can use the requested networks.
22212246

nova/tests/unit/network/test_neutronv2.py

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5813,6 +5813,74 @@ def test_migrate_instance_start_get_error(self, get_client_mock):
58135813
raise_exc=False,
58145814
global_request_id=self.context.global_id)])
58155815

5816+
@mock.patch('nova.network.neutronv2.api.get_client')
5817+
def test_get_requested_resource_for_instance_no_resource_request(
5818+
self, mock_get_client):
5819+
mock_client = mock_get_client.return_value
5820+
5821+
ports = {'ports': [
5822+
{
5823+
'id': uuids.port1,
5824+
'device_id': uuids.isnt1,
5825+
}
5826+
]}
5827+
mock_client.list_ports.return_value = ports
5828+
5829+
request_groups = self.api.get_requested_resource_for_instance(
5830+
self.context, uuids.inst1)
5831+
5832+
mock_client.list_ports.assert_called_with(
5833+
device_id=uuids.inst1, fields=['id', 'resource_request'])
5834+
self.assertEqual([], request_groups)
5835+
5836+
@mock.patch('nova.network.neutronv2.api.get_client')
5837+
def test_get_requested_resource_for_instance_no_ports(
5838+
self, mock_get_client):
5839+
mock_client = mock_get_client.return_value
5840+
5841+
ports = {'ports': []}
5842+
mock_client.list_ports.return_value = ports
5843+
5844+
request_groups = self.api.get_requested_resource_for_instance(
5845+
self.context, uuids.inst1)
5846+
5847+
mock_client.list_ports.assert_called_with(
5848+
device_id=uuids.inst1, fields=['id', 'resource_request'])
5849+
self.assertEqual([], request_groups)
5850+
5851+
@mock.patch('nova.network.neutronv2.api.get_client')
5852+
def test_get_requested_resource_for_instance_with_multiple_ports(
5853+
self, mock_get_client):
5854+
mock_client = mock_get_client.return_value
5855+
5856+
ports = {'ports': [
5857+
{
5858+
'id': uuids.port1,
5859+
'device_id': uuids.isnt1,
5860+
'resource_request': {
5861+
'resources': {'NET_BW_EGR_KILOBIT_PER_SEC': 10000}}
5862+
},
5863+
{
5864+
'id': uuids.port2,
5865+
'device_id': uuids.isnt1,
5866+
'resource_request': {}
5867+
},
5868+
]}
5869+
mock_client.list_ports.return_value = ports
5870+
5871+
request_groups = self.api.get_requested_resource_for_instance(
5872+
self.context, uuids.inst1)
5873+
5874+
mock_client.list_ports.assert_called_with(
5875+
device_id=uuids.inst1, fields=['id', 'resource_request'])
5876+
self.assertEqual(1, len(request_groups))
5877+
self.assertEqual(
5878+
{'NET_BW_EGR_KILOBIT_PER_SEC': 10000},
5879+
request_groups[0].resources)
5880+
self.assertEqual(
5881+
uuids.port1,
5882+
request_groups[0].requester_id)
5883+
58165884

58175885
class TestNeutronv2ModuleMethods(test.NoDBTestCase):
58185886

0 commit comments

Comments
 (0)