Merge "Explicitly fail if trying to attach SR-IOV port"
This commit is contained in:
commit
237ced4737
@ -17,8 +17,10 @@ assigned to only one guest and cannot be shared.
|
||||
|
||||
.. note::
|
||||
|
||||
For information on attaching virtual SR-IOV devices to guests, refer to the
|
||||
:neutron-doc:`Networking Guide <admin/config-sriov>`.
|
||||
For information on creating servers with virtual SR-IOV devices, refer to
|
||||
the :neutron-doc:`Networking Guide <admin/config-sriov>`. Attaching
|
||||
SR-IOV ports to existing servers is not currently supported, see
|
||||
`bug 1708433 <https://bugs.launchpad.net/nova/+bug/1708433>`_ for details.
|
||||
|
||||
To enable PCI passthrough, follow the steps below:
|
||||
|
||||
|
@ -885,6 +885,12 @@ class PortUpdateFailed(Invalid):
|
||||
msg_fmt = _("Port update failed for port %(port_id)s: %(reason)s")
|
||||
|
||||
|
||||
class AttachSRIOVPortNotSupported(Invalid):
|
||||
msg_fmt = _('Attaching SR-IOV port %(port_id)s to server '
|
||||
'%(instance_uuid)s is not supported. SR-IOV ports must be '
|
||||
'specified during server creation.')
|
||||
|
||||
|
||||
class FixedIpExists(NovaException):
|
||||
msg_fmt = _("Fixed IP %(address)s already exists.")
|
||||
|
||||
|
@ -650,7 +650,7 @@ class API(base_api.NetworkAPI):
|
||||
port_id)
|
||||
|
||||
def _validate_requested_port_ids(self, context, instance, neutron,
|
||||
requested_networks):
|
||||
requested_networks, attach=False):
|
||||
"""Processes and validates requested networks for allocation.
|
||||
|
||||
Iterates over the list of NetworkRequest objects, validating the
|
||||
@ -665,6 +665,9 @@ class API(base_api.NetworkAPI):
|
||||
:type neutron: neutronclient.v2_0.client.Client
|
||||
:param requested_networks: List of user-requested networks and/or ports
|
||||
:type requested_networks: nova.objects.NetworkRequestList
|
||||
:param attach: Boolean indicating if a port is being attached to an
|
||||
existing running instance. Should be False during server create.
|
||||
:type attach: bool
|
||||
:returns: tuple of:
|
||||
- ports: dict mapping of port id to port dict
|
||||
- ordered_networks: list of nova.objects.NetworkRequest objects
|
||||
@ -678,6 +681,8 @@ class API(base_api.NetworkAPI):
|
||||
attached to another instance.
|
||||
:raises nova.exception.PortNotUsableDNS: If a requested port has a
|
||||
value assigned to its dns_name attribute.
|
||||
:raises nova.exception.AttachSRIOVPortNotSupported: If a requested port
|
||||
is an SR-IOV port and ``attach=True``.
|
||||
"""
|
||||
ports = {}
|
||||
ordered_networks = []
|
||||
@ -715,6 +720,16 @@ class API(base_api.NetworkAPI):
|
||||
# Make sure the port is usable
|
||||
_ensure_no_port_binding_failure(port)
|
||||
|
||||
# Make sure the port can be attached.
|
||||
if attach:
|
||||
# SR-IOV port attach is not supported.
|
||||
vnic_type = port.get('binding:vnic_type',
|
||||
network_model.VNIC_TYPE_NORMAL)
|
||||
if vnic_type in network_model.VNIC_TYPES_SRIOV:
|
||||
raise exception.AttachSRIOVPortNotSupported(
|
||||
port_id=port['id'],
|
||||
instance_uuid=instance.uuid)
|
||||
|
||||
# If requesting a specific port, automatically process
|
||||
# the network for that port as if it were explicitly
|
||||
# requested.
|
||||
@ -955,7 +970,8 @@ class API(base_api.NetworkAPI):
|
||||
|
||||
def allocate_for_instance(self, context, instance, vpn,
|
||||
requested_networks, macs=None,
|
||||
security_groups=None, bind_host_id=None):
|
||||
security_groups=None, bind_host_id=None,
|
||||
attach=False):
|
||||
"""Allocate network resources for the instance.
|
||||
|
||||
:param context: The request context.
|
||||
@ -973,6 +989,8 @@ class API(base_api.NetworkAPI):
|
||||
:param security_groups: None or security groups to allocate for
|
||||
instance.
|
||||
:param bind_host_id: the host ID to attach to the ports being created.
|
||||
:param attach: Boolean indicating if a port is being attached to an
|
||||
existing running instance. Should be False during server create.
|
||||
:returns: network info as from get_instance_nw_info()
|
||||
"""
|
||||
LOG.debug('allocate_for_instance()', instance=instance)
|
||||
@ -993,7 +1011,7 @@ class API(base_api.NetworkAPI):
|
||||
#
|
||||
requested_ports_dict, ordered_networks = (
|
||||
self._validate_requested_port_ids(
|
||||
context, instance, neutron, requested_networks))
|
||||
context, instance, neutron, requested_networks, attach=attach))
|
||||
|
||||
nets = self._validate_requested_network_ids(
|
||||
context, instance, neutron, requested_networks, ordered_networks)
|
||||
@ -1542,7 +1560,7 @@ class API(base_api.NetworkAPI):
|
||||
tag=tag)])
|
||||
return self.allocate_for_instance(context, instance, vpn=False,
|
||||
requested_networks=requested_networks,
|
||||
bind_host_id=bind_host_id)
|
||||
bind_host_id=bind_host_id, attach=True)
|
||||
|
||||
def deallocate_port_for_instance(self, context, instance, port_id):
|
||||
"""Remove a specified port from the instance.
|
||||
|
@ -5923,7 +5923,8 @@ class TestAllocateForInstance(test.NoDBTestCase):
|
||||
self.assertEqual(requested_networks[0], ordered_networks[0])
|
||||
self.assertEqual('net-2', ordered_networks[1].network_id)
|
||||
|
||||
def _assert_validate_requested_port_ids_raises(self, exception, extras):
|
||||
def _assert_validate_requested_port_ids_raises(self, exception, extras,
|
||||
attach=False):
|
||||
api = neutronapi.API()
|
||||
mock_client = mock.Mock()
|
||||
requested_networks = objects.NetworkRequestList(objects=[
|
||||
@ -5937,7 +5938,8 @@ class TestAllocateForInstance(test.NoDBTestCase):
|
||||
mock_client.show_port.return_value = {"port": port}
|
||||
|
||||
self.assertRaises(exception, api._validate_requested_port_ids,
|
||||
self.context, self.instance, mock_client, requested_networks)
|
||||
self.context, self.instance, mock_client, requested_networks,
|
||||
attach=attach)
|
||||
|
||||
def test_validate_requested_port_ids_raise_not_usable(self):
|
||||
self._assert_validate_requested_port_ids_raises(
|
||||
@ -5959,6 +5961,12 @@ class TestAllocateForInstance(test.NoDBTestCase):
|
||||
exception.PortBindingFailed,
|
||||
{"binding:vif_type": model.VIF_TYPE_BINDING_FAILED})
|
||||
|
||||
def test_validate_requested_port_ids_raise_sriov(self):
|
||||
self._assert_validate_requested_port_ids_raises(
|
||||
exception.AttachSRIOVPortNotSupported,
|
||||
{"binding:vnic_type": model.VNIC_TYPE_DIRECT},
|
||||
attach=True)
|
||||
|
||||
def test_validate_requested_network_ids_success_auto_net(self):
|
||||
requested_networks = []
|
||||
ordered_networks = []
|
||||
|
Loading…
x
Reference in New Issue
Block a user