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.MultiattachNotSupportedOldMicroversion,
|
||||
exception.CertificateValidationFailed,
|
||||
exception.ServerCreateWithQoSPortNotSupported) as error:
|
||||
exception.CreateWithPortResourceRequestOldVersion) as error:
|
||||
raise exc.HTTPBadRequest(explanation=error.format_message())
|
||||
except (exception.PortInUse,
|
||||
exception.InstanceExists,
|
||||
|
|
|
@ -814,8 +814,11 @@ class API(base.Base):
|
|||
context, requested_networks, pci_request_info)
|
||||
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:
|
||||
raise exception.ServerCreateWithQoSPortNotSupported()
|
||||
raise exception.CreateWithPortResourceRequestOldVersion()
|
||||
|
||||
base_options = {
|
||||
'reservation_id': reservation_id,
|
||||
|
|
|
@ -2159,9 +2159,12 @@ class NetworksWithQoSPolicyNotSupported(Invalid):
|
|||
"instance %(instance_uuid)s. (Network ID is %(network_id)s)")
|
||||
|
||||
|
||||
class ServerCreateWithQoSPortNotSupported(Invalid):
|
||||
msg_fmt = _("Creating server with port having QoS policy is not "
|
||||
"supported.")
|
||||
class CreateWithPortResourceRequestOldVersion(Invalid):
|
||||
# TODO(gibi): Mention the specific microversion needed for the support
|
||||
# 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):
|
||||
|
|
|
@ -522,6 +522,10 @@ class API(base_api.NetworkAPI):
|
|||
# need resource allocation manipulation in placement but might also
|
||||
# need a new scheduling if resource on this host is not available.
|
||||
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)
|
||||
# NOTE(gibi): This limitation regarding server create can be
|
||||
# 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
|
||||
# set depending on neutron configuration, e.g. if QoS rules are
|
||||
# applied to the port/network and the resource_request API extension is
|
||||
# enabled.
|
||||
# applied to the port/network and the port-resource-request API
|
||||
# extension is enabled.
|
||||
resource_request = port.get('resource_request', None)
|
||||
return vnic_type, trusted, network_id, resource_request
|
||||
|
||||
|
@ -1978,8 +1982,8 @@ class API(base_api.NetworkAPI):
|
|||
context, neutron, network_id)
|
||||
|
||||
if resource_request:
|
||||
# NOTE(gibi): explicitly orphan the RequestGroup as we
|
||||
# never intended to save it to the DB.
|
||||
# NOTE(gibi): explicitly orphan the RequestGroup by setting
|
||||
# context=None as we never intended to save it to the DB.
|
||||
resource_requests.append(
|
||||
objects.RequestGroup.from_port_request(
|
||||
context=None,
|
||||
|
|
|
@ -5616,20 +5616,16 @@ class PortResourceRequestBasedSchedulingTest(
|
|||
server['fault']['message'])
|
||||
|
||||
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(
|
||||
client.OpenStackApiException,
|
||||
self.api.post_server, {'server': server_req})
|
||||
client.OpenStackApiException, self._create_server,
|
||||
flavor=self.flavor,
|
||||
networks=[{'port': self.neutron.port_with_resource_request['id']}])
|
||||
|
||||
self.assertEqual(400, ex.response.status_code)
|
||||
self.assertIn(
|
||||
'Creating server with port having QoS policy is not supported.',
|
||||
six.text_type(ex))
|
||||
"Creating servers with ports having resource requests, like a "
|
||||
"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):
|
||||
server = self._create_server(
|
||||
|
|
|
@ -6430,50 +6430,6 @@ class ComputeAPIUnitTestCase(_ComputeAPIUnitTestMixIn, test.NoDBTestCase):
|
|||
self.assertItemsEqual(['default', uuids.secgroup_uuid],
|
||||
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.object(compute_rpcapi.ComputeAPI, 'attach_interface')
|
||||
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,
|
||||
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):
|
||||
self._test_get_port_vnic_info(
|
||||
mock_get_client, None, model.VNIC_TYPE_NORMAL,
|
||||
|
@ -5256,7 +5256,7 @@ class TestNeutronv2WithMock(_TestNeutronv2Common):
|
|||
@mock.patch.object(neutronapi, 'get_client')
|
||||
def test_create_resource_requests(self, getclient,
|
||||
mock_get_port_vnic_info, mock_get_physnet_tunneled_info,
|
||||
mock_request_spec):
|
||||
mock_from_port_request):
|
||||
requested_networks = objects.NetworkRequestList(
|
||||
objects = [
|
||||
objects.NetworkRequest(port_id=uuids.portid_1),
|
||||
|
@ -5288,7 +5288,7 @@ class TestNeutronv2WithMock(_TestNeutronv2Common):
|
|||
]
|
||||
api = neutronapi.API()
|
||||
|
||||
mock_request_spec.side_effect = [
|
||||
mock_from_port_request.side_effect = [
|
||||
mock.sentinel.request_group1,
|
||||
mock.sentinel.request_group2,
|
||||
]
|
||||
|
@ -5322,7 +5322,7 @@ class TestNeutronv2WithMock(_TestNeutronv2Common):
|
|||
['physnet1', 'physnet2', 'physnet3', 'physnet4'],
|
||||
network_metadata.physnets)
|
||||
self.assertTrue(network_metadata.tunneled)
|
||||
mock_request_spec.assert_has_calls([
|
||||
mock_from_port_request.assert_has_calls([
|
||||
mock.call(
|
||||
context=None,
|
||||
port_uuid=uuids.portid_2,
|
||||
|
|
Loading…
Reference in New Issue