Merge "Fallback to same-cell resize with qos ports"
This commit is contained in:
commit
06c0a4e6bc
@ -30,7 +30,8 @@ neutron ports having resource requests if both the source and destination
|
||||
compute services are upgraded to 20.0.0 (Train) and the
|
||||
``[upgrade_levels]/compute`` configuration does not prevent the computes from
|
||||
using the latest RPC version. However cross cell resize and cross cell migrate
|
||||
operations are still not supported with such ports.
|
||||
operations are still not supported with such ports and Nova will fall back to
|
||||
same-cell resize if the server has such ports.
|
||||
|
||||
As of 21.0.0 (Ussuri), nova supports evacuating, live migrating and unshelving
|
||||
servers with neutron ports having resource requests.
|
||||
|
@ -237,7 +237,8 @@ These are known to not yet be supported in the code:
|
||||
|
||||
* Instances with ports attached that have
|
||||
:doc:`bandwidth-aware </admin/ports-with-resource-requests>` resource
|
||||
provider allocations.
|
||||
provider allocations. Nova falls back to same-cell resize if the server has
|
||||
such ports.
|
||||
* Rescheduling to alternative hosts within the same target cell in case the
|
||||
primary selected host fails the ``prep_snapshot_based_resize_at_dest`` call.
|
||||
|
||||
|
@ -3852,8 +3852,7 @@ class API(base.Base):
|
||||
migration,
|
||||
migration.source_compute)
|
||||
|
||||
@staticmethod
|
||||
def _allow_cross_cell_resize(context, instance):
|
||||
def _allow_cross_cell_resize(self, context, instance):
|
||||
"""Determine if the request can perform a cross-cell resize on this
|
||||
instance.
|
||||
|
||||
@ -3861,8 +3860,6 @@ class API(base.Base):
|
||||
:param instance: Instance object being resized
|
||||
:returns: True if cross-cell resize is allowed, False otherwise
|
||||
"""
|
||||
# TODO(gibi): do not allow cross cell migration if the instance has
|
||||
# neutron ports with resource request. See bug 1907522.
|
||||
# First check to see if the requesting project/user is allowed by
|
||||
# policy to perform cross-cell resize.
|
||||
allowed = context.can(
|
||||
@ -3885,7 +3882,17 @@ class API(base.Base):
|
||||
'version in the deployment %s is less than %s so '
|
||||
'cross-cell resize is not allowed at this time.',
|
||||
min_compute_version, MIN_COMPUTE_CROSS_CELL_RESIZE)
|
||||
allowed = False
|
||||
return False
|
||||
|
||||
if self.network_api.get_requested_resource_for_instance(
|
||||
context, instance.uuid):
|
||||
LOG.info(
|
||||
'Request is allowed by policy to perform cross-cell '
|
||||
'resize but the instance has ports with resource request '
|
||||
'and cross-cell resize is not supported with such ports.',
|
||||
instance=instance)
|
||||
return False
|
||||
|
||||
return allowed
|
||||
|
||||
@staticmethod
|
||||
|
@ -8025,41 +8025,36 @@ class CrossCellResizeWithQoSPort(PortResourceRequestBasedSchedulingTestBase):
|
||||
# host is in a different cell and while cross cell migration is
|
||||
# enabled it is not supported for neutron ports with resource
|
||||
# request.
|
||||
# FIXME(gibi): We expect this to fail with NoValidHost.
|
||||
# Unfortunately it fails due to sending an invalid port binding to
|
||||
# Neutron today. This is bug 1907522.
|
||||
self.api.post_server_action(server['id'], {'migrate': None})
|
||||
self._wait_for_migration_status(server, ['error'])
|
||||
# FIXME(gibi): This is also the result of the bug1907522 as the
|
||||
# cleanup after the failure is incomplete.
|
||||
self._wait_for_server_parameter(
|
||||
server,
|
||||
{'status': 'RESIZE', 'OS-EXT-STS:task_state': 'resize_prep'})
|
||||
{'status': 'ACTIVE', 'OS-EXT-SRV-ATTR:host': 'host1'})
|
||||
event = self._wait_for_action_fail_completion(
|
||||
server, 'migrate', 'conductor_migrate_server')
|
||||
# This is just the last exception in the chain of exceptions
|
||||
# happening after the port binding fails.
|
||||
self.assertIn(
|
||||
'exception.InstanceInfoCacheNotFound', event['traceback'])
|
||||
# This is the root case
|
||||
'exception.NoValidHost', event['traceback'])
|
||||
self.assertIn(
|
||||
'Request is allowed by policy to perform cross-cell resize '
|
||||
'but the instance has ports with resource request and '
|
||||
'cross-cell resize is not supported with such ports.',
|
||||
self.stdlog.logger.output)
|
||||
self.assertNotIn(
|
||||
'nova.exception.PortBindingFailed: Binding failed for port',
|
||||
self.stdlog.logger.output)
|
||||
|
||||
# Now start a new compute in the same cell as the instance and retry
|
||||
# the migration.
|
||||
#
|
||||
# This should work after the fallback to same cell resize is
|
||||
# implemented
|
||||
#
|
||||
# self._start_compute('host3', cell_name='cell1')
|
||||
#
|
||||
# with mock.patch(
|
||||
# 'nova.network.neutron.API._create_port_binding',
|
||||
# side_effect=spy_on_create_binding, autospec=True
|
||||
# ):
|
||||
# server = self._migrate_server(server)
|
||||
# self.assertEqual('host3', server['OS-EXT-SRV-ATTR:host'])
|
||||
self._start_compute('host3', cell_name='cell1')
|
||||
self.compute3_rp_uuid = self._get_provider_uuid_by_host('host3')
|
||||
self._create_networking_rp_tree('host3', self.compute3_rp_uuid)
|
||||
|
||||
with mock.patch(
|
||||
'nova.network.neutron.API._create_port_binding',
|
||||
side_effect=spy_on_create_binding, autospec=True
|
||||
):
|
||||
server = self._migrate_server(server)
|
||||
self.assertEqual('host3', server['OS-EXT-SRV-ATTR:host'])
|
||||
|
||||
self._delete_server_and_check_allocations(
|
||||
server, qos_normal_port, qos_sriov_port)
|
||||
|
@ -7522,7 +7522,8 @@ class ComputeAPIUnitTestCase(_ComputeAPIUnitTestMixIn, test.NoDBTestCase):
|
||||
version is not new enough.
|
||||
"""
|
||||
instance = objects.Instance(
|
||||
project_id='fake-project', user_id='fake-user')
|
||||
project_id='fake-project', user_id='fake-user',
|
||||
uuid=uuids.instance)
|
||||
with mock.patch.object(self.context, 'can', return_value=True) as can:
|
||||
self.assertFalse(self.compute_api._allow_cross_cell_resize(
|
||||
self.context, instance))
|
||||
@ -7530,20 +7531,45 @@ class ComputeAPIUnitTestCase(_ComputeAPIUnitTestMixIn, test.NoDBTestCase):
|
||||
mock_get_min_ver.assert_called_once_with(
|
||||
self.context, ['nova-compute'])
|
||||
|
||||
@mock.patch('nova.network.neutron.API.get_requested_resource_for_instance',
|
||||
return_value=[objects.RequestGroup()])
|
||||
@mock.patch('nova.objects.service.get_minimum_version_all_cells',
|
||||
return_value=compute_api.MIN_COMPUTE_CROSS_CELL_RESIZE)
|
||||
def test_allow_cross_cell_resize_true(self, mock_get_min_ver):
|
||||
def test_allow_cross_cell_resize_false_port_with_resource_req(
|
||||
self, mock_get_min_ver, mock_get_res_req):
|
||||
"""Policy allows cross-cell resize but minimum nova-compute service
|
||||
version is not new enough.
|
||||
"""
|
||||
instance = objects.Instance(
|
||||
project_id='fake-project', user_id='fake-user',
|
||||
uuid=uuids.instance)
|
||||
with mock.patch.object(self.context, 'can', return_value=True) as can:
|
||||
self.assertFalse(self.compute_api._allow_cross_cell_resize(
|
||||
self.context, instance))
|
||||
can.assert_called_once()
|
||||
mock_get_min_ver.assert_called_once_with(
|
||||
self.context, ['nova-compute'])
|
||||
mock_get_res_req.assert_called_once_with(self.context, uuids.instance)
|
||||
|
||||
@mock.patch('nova.network.neutron.API.get_requested_resource_for_instance',
|
||||
return_value=[])
|
||||
@mock.patch('nova.objects.service.get_minimum_version_all_cells',
|
||||
return_value=compute_api.MIN_COMPUTE_CROSS_CELL_RESIZE)
|
||||
def test_allow_cross_cell_resize_true(
|
||||
self, mock_get_min_ver, mock_get_res_req):
|
||||
"""Policy allows cross-cell resize and minimum nova-compute service
|
||||
version is new enough.
|
||||
"""
|
||||
instance = objects.Instance(
|
||||
project_id='fake-project', user_id='fake-user')
|
||||
project_id='fake-project', user_id='fake-user',
|
||||
uuid=uuids.instance)
|
||||
with mock.patch.object(self.context, 'can', return_value=True) as can:
|
||||
self.assertTrue(self.compute_api._allow_cross_cell_resize(
|
||||
self.context, instance))
|
||||
can.assert_called_once()
|
||||
mock_get_min_ver.assert_called_once_with(
|
||||
self.context, ['nova-compute'])
|
||||
mock_get_res_req.assert_called_once_with(self.context, uuids.instance)
|
||||
|
||||
def _test_block_accelerators(self, instance, args_info,
|
||||
until_service=None):
|
||||
|
@ -4,4 +4,6 @@ issues:
|
||||
When the tempest test coverage was added for resize and cold migrate
|
||||
with neutron ports having QoS minimum bandwidth policy rules we
|
||||
discovered that the cross cell resize code path cannot handle such ports.
|
||||
See bug https://bugs.launchpad.net/nova/+bug/1907522 for details.
|
||||
See bug https://bugs.launchpad.net/nova/+bug/1907522 for details. A fix
|
||||
was implemented that makes sure that Nova falls back to same-cell resize if
|
||||
the server has such ports.
|
||||
|
Loading…
x
Reference in New Issue
Block a user