Merge "Fup for the bandwidth resource provider series"
This commit is contained in:
commit
f77791954d
|
@ -651,7 +651,7 @@ class ServersController(wsgi.Controller):
|
||||||
exception.UnableToAutoAllocateNetwork,
|
exception.UnableToAutoAllocateNetwork,
|
||||||
exception.MultiattachNotSupportedOldMicroversion,
|
exception.MultiattachNotSupportedOldMicroversion,
|
||||||
exception.CertificateValidationFailed,
|
exception.CertificateValidationFailed,
|
||||||
exception.ServerCreateWithQoSPortNotSupported) as error:
|
exception.CreateWithPortResourceRequestOldVersion) as error:
|
||||||
raise exc.HTTPBadRequest(explanation=error.format_message())
|
raise exc.HTTPBadRequest(explanation=error.format_message())
|
||||||
except (exception.PortInUse,
|
except (exception.PortInUse,
|
||||||
exception.InstanceExists,
|
exception.InstanceExists,
|
||||||
|
|
|
@ -814,8 +814,11 @@ class API(base.Base):
|
||||||
context, requested_networks, pci_request_info)
|
context, requested_networks, pci_request_info)
|
||||||
network_metadata, port_resource_requests = result
|
network_metadata, port_resource_requests = result
|
||||||
|
|
||||||
|
# Creating servers with ports that have resource requests, like QoS
|
||||||
|
# minimum bandwidth rules, is only supported in a requested minimum
|
||||||
|
# microversion.
|
||||||
if port_resource_requests and not supports_port_resource_request:
|
if port_resource_requests and not supports_port_resource_request:
|
||||||
raise exception.ServerCreateWithQoSPortNotSupported()
|
raise exception.CreateWithPortResourceRequestOldVersion()
|
||||||
|
|
||||||
base_options = {
|
base_options = {
|
||||||
'reservation_id': reservation_id,
|
'reservation_id': reservation_id,
|
||||||
|
|
|
@ -2159,9 +2159,12 @@ class NetworksWithQoSPolicyNotSupported(Invalid):
|
||||||
"instance %(instance_uuid)s. (Network ID is %(network_id)s)")
|
"instance %(instance_uuid)s. (Network ID is %(network_id)s)")
|
||||||
|
|
||||||
|
|
||||||
class ServerCreateWithQoSPortNotSupported(Invalid):
|
class CreateWithPortResourceRequestOldVersion(Invalid):
|
||||||
msg_fmt = _("Creating server with port having QoS policy is not "
|
# TODO(gibi): Mention the specific microversion needed for the support
|
||||||
"supported.")
|
# after such microversion is merged
|
||||||
|
msg_fmt = _("Creating servers with ports having resource requests, like a "
|
||||||
|
"port with a QoS minimum bandwidth policy, is not supported "
|
||||||
|
"with this microversion")
|
||||||
|
|
||||||
|
|
||||||
class InvalidReservedMemoryPagesOption(Invalid):
|
class InvalidReservedMemoryPagesOption(Invalid):
|
||||||
|
|
|
@ -522,6 +522,10 @@ class API(base_api.NetworkAPI):
|
||||||
# need resource allocation manipulation in placement but might also
|
# need resource allocation manipulation in placement but might also
|
||||||
# need a new scheduling if resource on this host is not available.
|
# need a new scheduling if resource on this host is not available.
|
||||||
if port.get('resource_request', None):
|
if port.get('resource_request', None):
|
||||||
|
msg = _(
|
||||||
|
"The auto-created port %(port_id)s is being deleted due "
|
||||||
|
"to its network having QoS policy.")
|
||||||
|
LOG.info(msg, {'port_id': port_id})
|
||||||
self._cleanup_created_port(port_client, port_id, instance)
|
self._cleanup_created_port(port_client, port_id, instance)
|
||||||
# NOTE(gibi): This limitation regarding server create can be
|
# NOTE(gibi): This limitation regarding server create can be
|
||||||
# removed when the port creation is moved to the conductor. But
|
# removed when the port creation is moved to the conductor. But
|
||||||
|
@ -1932,8 +1936,8 @@ class API(base_api.NetworkAPI):
|
||||||
|
|
||||||
# NOTE(gibi): Get the port resource_request which may or may not be
|
# NOTE(gibi): Get the port resource_request which may or may not be
|
||||||
# set depending on neutron configuration, e.g. if QoS rules are
|
# set depending on neutron configuration, e.g. if QoS rules are
|
||||||
# applied to the port/network and the resource_request API extension is
|
# applied to the port/network and the port-resource-request API
|
||||||
# enabled.
|
# extension is enabled.
|
||||||
resource_request = port.get('resource_request', None)
|
resource_request = port.get('resource_request', None)
|
||||||
return vnic_type, trusted, network_id, resource_request
|
return vnic_type, trusted, network_id, resource_request
|
||||||
|
|
||||||
|
@ -1978,8 +1982,8 @@ class API(base_api.NetworkAPI):
|
||||||
context, neutron, network_id)
|
context, neutron, network_id)
|
||||||
|
|
||||||
if resource_request:
|
if resource_request:
|
||||||
# NOTE(gibi): explicitly orphan the RequestGroup as we
|
# NOTE(gibi): explicitly orphan the RequestGroup by setting
|
||||||
# never intended to save it to the DB.
|
# context=None as we never intended to save it to the DB.
|
||||||
resource_requests.append(
|
resource_requests.append(
|
||||||
objects.RequestGroup.from_port_request(
|
objects.RequestGroup.from_port_request(
|
||||||
context=None,
|
context=None,
|
||||||
|
|
|
@ -5616,20 +5616,16 @@ class PortResourceRequestBasedSchedulingTest(
|
||||||
server['fault']['message'])
|
server['fault']['message'])
|
||||||
|
|
||||||
def test_create_server_with_port_resource_request_old_microversion(self):
|
def test_create_server_with_port_resource_request_old_microversion(self):
|
||||||
server_req = self._build_minimal_create_server_request(
|
|
||||||
self.api, 'bandwidth-aware-server',
|
|
||||||
image_uuid='76fa36fc-c930-4bf3-8c8a-ea2a2420deb6',
|
|
||||||
flavor_id=self.flavor['id'],
|
|
||||||
networks=[{'port': self.neutron.port_with_resource_request['id']}])
|
|
||||||
|
|
||||||
ex = self.assertRaises(
|
ex = self.assertRaises(
|
||||||
client.OpenStackApiException,
|
client.OpenStackApiException, self._create_server,
|
||||||
self.api.post_server, {'server': server_req})
|
flavor=self.flavor,
|
||||||
|
networks=[{'port': self.neutron.port_with_resource_request['id']}])
|
||||||
|
|
||||||
self.assertEqual(400, ex.response.status_code)
|
self.assertEqual(400, ex.response.status_code)
|
||||||
self.assertIn(
|
self.assertIn(
|
||||||
'Creating server with port having QoS policy is not supported.',
|
"Creating servers with ports having resource requests, like a "
|
||||||
six.text_type(ex))
|
"port with a QoS minimum bandwidth policy, is not supported with "
|
||||||
|
"this microversion", six.text_type(ex))
|
||||||
|
|
||||||
def test_resize_server_with_port_resource_request_old_microversion(self):
|
def test_resize_server_with_port_resource_request_old_microversion(self):
|
||||||
server = self._create_server(
|
server = self._create_server(
|
||||||
|
|
|
@ -6430,50 +6430,6 @@ class ComputeAPIUnitTestCase(_ComputeAPIUnitTestMixIn, test.NoDBTestCase):
|
||||||
self.assertItemsEqual(['default', uuids.secgroup_uuid],
|
self.assertItemsEqual(['default', uuids.secgroup_uuid],
|
||||||
security_groups)
|
security_groups)
|
||||||
|
|
||||||
@mock.patch('nova.network.neutronv2.api.API.validate_networks')
|
|
||||||
@mock.patch('nova.network.neutronv2.api.API.create_resource_requests')
|
|
||||||
def test_validate_and_build_base_options_checks_resource_request(
|
|
||||||
self, mock_neutron_create_resource_requests,
|
|
||||||
mock_validate_network):
|
|
||||||
"""Checks that validate_and_build_base_options raises if the request
|
|
||||||
contains port with resource request but API request does not use the
|
|
||||||
microversion enabling such support.
|
|
||||||
"""
|
|
||||||
instance_type = objects.Flavor(**test_flavor.fake_flavor)
|
|
||||||
boot_meta = metadata = {}
|
|
||||||
kernel_id = ramdisk_id = key_name = key_data = user_data = \
|
|
||||||
access_ip_v4 = access_ip_v6 = config_drive = \
|
|
||||||
auto_disk_config = reservation_id = None
|
|
||||||
requested_secgroups = ['default']
|
|
||||||
requested_networks = objects.NetworkRequestList(objects=[
|
|
||||||
objects.NetworkRequest(port_id=uuids.port_id)])
|
|
||||||
mock_neutron_create_resource_requests.return_value = (
|
|
||||||
None, [objects.RequestGroup()])
|
|
||||||
max_count = 1
|
|
||||||
|
|
||||||
# This expected not to raise
|
|
||||||
supports_port_resource_request = True
|
|
||||||
self.compute_api._validate_and_build_base_options(
|
|
||||||
self.context, instance_type, boot_meta, uuids.image_href,
|
|
||||||
mock.sentinel.image_id, kernel_id, ramdisk_id,
|
|
||||||
'fake-display-name', 'fake-description', key_name,
|
|
||||||
key_data, requested_secgroups, 'fake-az', user_data,
|
|
||||||
metadata, access_ip_v4, access_ip_v6, requested_networks,
|
|
||||||
config_drive, auto_disk_config, reservation_id, max_count,
|
|
||||||
supports_port_resource_request)
|
|
||||||
|
|
||||||
supports_port_resource_request = False
|
|
||||||
self.assertRaises(
|
|
||||||
exception.ServerCreateWithQoSPortNotSupported,
|
|
||||||
self.compute_api._validate_and_build_base_options,
|
|
||||||
self.context, instance_type, boot_meta, uuids.image_href,
|
|
||||||
mock.sentinel.image_id, kernel_id, ramdisk_id,
|
|
||||||
'fake-display-name', 'fake-description', key_name,
|
|
||||||
key_data, requested_secgroups, 'fake-az', user_data,
|
|
||||||
metadata, access_ip_v4, access_ip_v6, requested_networks,
|
|
||||||
config_drive, auto_disk_config, reservation_id, max_count,
|
|
||||||
supports_port_resource_request)
|
|
||||||
|
|
||||||
@mock.patch('nova.compute.api.API._record_action_start')
|
@mock.patch('nova.compute.api.API._record_action_start')
|
||||||
@mock.patch.object(compute_rpcapi.ComputeAPI, 'attach_interface')
|
@mock.patch.object(compute_rpcapi.ComputeAPI, 'attach_interface')
|
||||||
def test_tagged_interface_attach(self, mock_attach, mock_record):
|
def test_tagged_interface_attach(self, mock_attach, mock_record):
|
||||||
|
|
|
@ -3070,7 +3070,7 @@ class TestNeutronv2(TestNeutronv2Base):
|
||||||
self._test_get_port_vnic_info(mock_get_client, None,
|
self._test_get_port_vnic_info(mock_get_client, None,
|
||||||
model.VNIC_TYPE_NORMAL)
|
model.VNIC_TYPE_NORMAL)
|
||||||
|
|
||||||
@mock.patch.object(neutronapi, 'get_client', return_value=mock.Mock())
|
@mock.patch.object(neutronapi, 'get_client')
|
||||||
def test_get_port_vnic_info_requested_resources(self, mock_get_client):
|
def test_get_port_vnic_info_requested_resources(self, mock_get_client):
|
||||||
self._test_get_port_vnic_info(
|
self._test_get_port_vnic_info(
|
||||||
mock_get_client, None, model.VNIC_TYPE_NORMAL,
|
mock_get_client, None, model.VNIC_TYPE_NORMAL,
|
||||||
|
@ -5256,7 +5256,7 @@ class TestNeutronv2WithMock(_TestNeutronv2Common):
|
||||||
@mock.patch.object(neutronapi, 'get_client')
|
@mock.patch.object(neutronapi, 'get_client')
|
||||||
def test_create_resource_requests(self, getclient,
|
def test_create_resource_requests(self, getclient,
|
||||||
mock_get_port_vnic_info, mock_get_physnet_tunneled_info,
|
mock_get_port_vnic_info, mock_get_physnet_tunneled_info,
|
||||||
mock_request_spec):
|
mock_from_port_request):
|
||||||
requested_networks = objects.NetworkRequestList(
|
requested_networks = objects.NetworkRequestList(
|
||||||
objects = [
|
objects = [
|
||||||
objects.NetworkRequest(port_id=uuids.portid_1),
|
objects.NetworkRequest(port_id=uuids.portid_1),
|
||||||
|
@ -5288,7 +5288,7 @@ class TestNeutronv2WithMock(_TestNeutronv2Common):
|
||||||
]
|
]
|
||||||
api = neutronapi.API()
|
api = neutronapi.API()
|
||||||
|
|
||||||
mock_request_spec.side_effect = [
|
mock_from_port_request.side_effect = [
|
||||||
mock.sentinel.request_group1,
|
mock.sentinel.request_group1,
|
||||||
mock.sentinel.request_group2,
|
mock.sentinel.request_group2,
|
||||||
]
|
]
|
||||||
|
@ -5322,7 +5322,7 @@ class TestNeutronv2WithMock(_TestNeutronv2Common):
|
||||||
['physnet1', 'physnet2', 'physnet3', 'physnet4'],
|
['physnet1', 'physnet2', 'physnet3', 'physnet4'],
|
||||||
network_metadata.physnets)
|
network_metadata.physnets)
|
||||||
self.assertTrue(network_metadata.tunneled)
|
self.assertTrue(network_metadata.tunneled)
|
||||||
mock_request_spec.assert_has_calls([
|
mock_from_port_request.assert_has_calls([
|
||||||
mock.call(
|
mock.call(
|
||||||
context=None,
|
context=None,
|
||||||
port_uuid=uuids.portid_2,
|
port_uuid=uuids.portid_2,
|
||||||
|
|
Loading…
Reference in New Issue