Skip to content

Commit 6b57575

Browse files
author
Balazs Gibizer
committed
Fallback to same-cell resize with qos ports
The cross-cell resize code does not consider neutron ports with resource request. To avoid migration failures this patch makes nova to fall back to same cell resize if the instance has neutron ports with resource request. The stable only difference is due to change in the reproduction patch Id91d2e817ef6bd21124bb840bdb098054e9753b8 on stable. Change-Id: Icaad4b2375b491c8a7e87fb6f4977ae2e13e8190 Closes-Bug: #1907522 Closes-Bug: #1907511 (cherry picked from commit 1c056c3)
1 parent 7366e3c commit 6b57575

File tree

6 files changed

+74
-32
lines changed

6 files changed

+74
-32
lines changed

api-guide/source/port_with_resource_request.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ neutron ports having resource requests if both the source and destination
3030
compute services are upgraded to 20.0.0 (Train) and the
3131
``[upgrade_levels]/compute`` configuration does not prevent the computes from
3232
using the latest RPC version. However cross cell resize and cross cell migrate
33-
operations are still not supported with such ports.
33+
operations are still not supported with such ports and Nova will fall back to
34+
same-cell resize if the server has such ports.
3435

3536
As of 21.0.0 (Ussuri), nova supports evacuating, live migrating and unshelving
3637
servers with neutron ports having resource requests.

doc/source/admin/configuration/cross-cell-resize.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,8 @@ These are known to not yet be supported in the code:
237237

238238
* Instances with ports attached that have
239239
:doc:`bandwidth-aware </admin/ports-with-resource-requests>` resource
240-
provider allocations.
240+
provider allocations. Nova falls back to same-cell resize if the server has
241+
such ports.
241242
* Rescheduling to alternative hosts within the same target cell in case the
242243
primary selected host fails the ``prep_snapshot_based_resize_at_dest`` call.
243244

nova/compute/api.py

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3870,17 +3870,14 @@ def confirm_resize(self, context, instance, migration=None):
38703870
migration,
38713871
migration.source_compute)
38723872

3873-
@staticmethod
3874-
def _allow_cross_cell_resize(context, instance):
3873+
def _allow_cross_cell_resize(self, context, instance):
38753874
"""Determine if the request can perform a cross-cell resize on this
38763875
instance.
38773876
38783877
:param context: nova auth request context for the resize operation
38793878
:param instance: Instance object being resized
38803879
:returns: True if cross-cell resize is allowed, False otherwise
38813880
"""
3882-
# TODO(gibi): do not allow cross cell migration if the instance has
3883-
# neutron ports with resource request. See bug 1907522.
38843881
# First check to see if the requesting project/user is allowed by
38853882
# policy to perform cross-cell resize.
38863883
allowed = context.can(
@@ -3903,7 +3900,17 @@ def _allow_cross_cell_resize(context, instance):
39033900
'version in the deployment %s is less than %s so '
39043901
'cross-cell resize is not allowed at this time.',
39053902
min_compute_version, MIN_COMPUTE_CROSS_CELL_RESIZE)
3906-
allowed = False
3903+
return False
3904+
3905+
if self.network_api.get_requested_resource_for_instance(
3906+
context, instance.uuid):
3907+
LOG.info(
3908+
'Request is allowed by policy to perform cross-cell '
3909+
'resize but the instance has ports with resource request '
3910+
'and cross-cell resize is not supported with such ports.',
3911+
instance=instance)
3912+
return False
3913+
39073914
return allowed
39083915

39093916
@staticmethod

nova/tests/functional/test_servers.py

Lines changed: 26 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -8333,35 +8333,40 @@ def spy_on_create_binding(context, client, port_id, data):
83338333
# host is in a different cell and while cross cell migration is
83348334
# enabled it is not supported for neutron ports with resource
83358335
# request.
8336-
# FIXME(gibi): We expect this to fail with NoValidHost.
8337-
# Unfortunately it fails by not finding the target compute service
8338-
# in the same cell the source service. This is bug 1907511. If
8339-
# there would be a standalone fix for 1907511 then the next failure
8340-
# would be 1907522. Our coming fix will fix both bug with a same
8341-
# fix.
83428336
self.api.post_server_action(server['id'], {'migrate': None})
83438337
self._wait_for_migration_status(server, ['error'])
8344-
self._wait_for_action_fail_completion(
8338+
self._wait_for_server_parameter(
8339+
server,
8340+
{'status': 'ACTIVE', 'OS-EXT-SRV-ATTR:host': 'host1'})
8341+
event = self._wait_for_action_fail_completion(
83458342
server, 'migrate', 'conductor_migrate_server')
8346-
# This is the root case
83478343
self.assertIn(
8344+
'exception.NoValidHost', event['traceback'])
8345+
log = self.stdlog.logger.output
8346+
self.assertIn(
8347+
'Request is allowed by policy to perform cross-cell resize '
8348+
'but the instance has ports with resource request and '
8349+
'cross-cell resize is not supported with such ports.',
8350+
log)
8351+
self.assertNotIn(
8352+
'nova.exception.PortBindingFailed: Binding failed for port',
8353+
log)
8354+
self.assertNotIn(
83488355
"AttributeError: 'NoneType' object has no attribute 'version'",
8349-
self.stdlog.logger.output)
8356+
log)
83508357

83518358
# Now start a new compute in the same cell as the instance and retry
83528359
# the migration.
8353-
#
8354-
# This should work after the fallback to same cell resize is
8355-
# implemented
8356-
#
8357-
# self._start_compute('host3', cell_name='cell1')
8358-
#
8359-
# with mock.patch(
8360-
# 'nova.network.neutron.API._create_port_binding',
8361-
# side_effect=spy_on_create_binding, autospec=True
8362-
# ):
8363-
# server = self._migrate_server(server)
8364-
# self.assertEqual('host3', server['OS-EXT-SRV-ATTR:host'])
8360+
self._start_compute('host3', cell_name='cell1')
8361+
self.compute3_rp_uuid = self._get_provider_uuid_by_host('host3')
8362+
self._create_networking_rp_tree('host3', self.compute3_rp_uuid)
8363+
8364+
with mock.patch(
8365+
'nova.network.neutron.API._create_port_binding',
8366+
side_effect=spy_on_create_binding, autospec=True
8367+
):
8368+
server = self._migrate_server(server)
8369+
self.assertEqual('host3', server['OS-EXT-SRV-ATTR:host'])
83658370

83668371
self._delete_server_and_check_allocations(
83678372
server, qos_normal_port, qos_sriov_port)

nova/tests/unit/compute/test_api.py

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7522,28 +7522,54 @@ def test_allow_cross_cell_resize_false_old_version(self, mock_get_min_ver):
75227522
version is not new enough.
75237523
"""
75247524
instance = objects.Instance(
7525-
project_id='fake-project', user_id='fake-user')
7525+
project_id='fake-project', user_id='fake-user',
7526+
uuid=uuids.instance)
7527+
with mock.patch.object(self.context, 'can', return_value=True) as can:
7528+
self.assertFalse(self.compute_api._allow_cross_cell_resize(
7529+
self.context, instance))
7530+
can.assert_called_once()
7531+
mock_get_min_ver.assert_called_once_with(
7532+
self.context, ['nova-compute'])
7533+
7534+
@mock.patch('nova.network.neutron.API.get_requested_resource_for_instance',
7535+
return_value=[objects.RequestGroup()])
7536+
@mock.patch('nova.objects.service.get_minimum_version_all_cells',
7537+
return_value=compute_api.MIN_COMPUTE_CROSS_CELL_RESIZE)
7538+
def test_allow_cross_cell_resize_false_port_with_resource_req(
7539+
self, mock_get_min_ver, mock_get_res_req):
7540+
"""Policy allows cross-cell resize but minimum nova-compute service
7541+
version is not new enough.
7542+
"""
7543+
instance = objects.Instance(
7544+
project_id='fake-project', user_id='fake-user',
7545+
uuid=uuids.instance)
75267546
with mock.patch.object(self.context, 'can', return_value=True) as can:
75277547
self.assertFalse(self.compute_api._allow_cross_cell_resize(
75287548
self.context, instance))
75297549
can.assert_called_once()
75307550
mock_get_min_ver.assert_called_once_with(
75317551
self.context, ['nova-compute'])
7552+
mock_get_res_req.assert_called_once_with(self.context, uuids.instance)
75327553

7554+
@mock.patch('nova.network.neutron.API.get_requested_resource_for_instance',
7555+
return_value=[])
75337556
@mock.patch('nova.objects.service.get_minimum_version_all_cells',
75347557
return_value=compute_api.MIN_COMPUTE_CROSS_CELL_RESIZE)
7535-
def test_allow_cross_cell_resize_true(self, mock_get_min_ver):
7558+
def test_allow_cross_cell_resize_true(
7559+
self, mock_get_min_ver, mock_get_res_req):
75367560
"""Policy allows cross-cell resize and minimum nova-compute service
75377561
version is new enough.
75387562
"""
75397563
instance = objects.Instance(
7540-
project_id='fake-project', user_id='fake-user')
7564+
project_id='fake-project', user_id='fake-user',
7565+
uuid=uuids.instance)
75417566
with mock.patch.object(self.context, 'can', return_value=True) as can:
75427567
self.assertTrue(self.compute_api._allow_cross_cell_resize(
75437568
self.context, instance))
75447569
can.assert_called_once()
75457570
mock_get_min_ver.assert_called_once_with(
75467571
self.context, ['nova-compute'])
7572+
mock_get_res_req.assert_called_once_with(self.context, uuids.instance)
75477573

75487574
def _test_block_accelerators(self, instance, args_info,
75497575
until_service=None):

releasenotes/notes/cros-scell-resize-not-supported-with-ports-having-resource-request-a8e1029ef5983793.yaml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,6 @@ issues:
44
When the tempest test coverage was added for resize and cold migrate
55
with neutron ports having QoS minimum bandwidth policy rules we
66
discovered that the cross cell resize code path cannot handle such ports.
7-
See bug https://bugs.launchpad.net/nova/+bug/1907522 for details.
7+
See bug https://bugs.launchpad.net/nova/+bug/1907522 for details. A fix
8+
was implemented that makes sure that Nova falls back to same-cell resize if
9+
the server has such ports.

0 commit comments

Comments
 (0)