diff options
author | Zuul <zuul@review.opendev.org> | 2021-01-30 17:38:43 +0000 |
---|---|---|
committer | Gerrit Code Review <review@openstack.org> | 2021-01-30 17:38:43 +0000 |
commit | cf1db74731198b573cc3693c7923c665b43fcf9c (patch) | |
tree | 121a55d6ee705c6658f75f13fba82d20f583c37d | |
parent | 795aa6c25d85b05f6dfc7252f14bdc058bab9419 (diff) | |
parent | 6b57575092aa5f16f51e5af8b0e62617f46b420a (diff) | |
download | nova-cf1db74731198b573cc3693c7923c665b43fcf9c.tar.gz |
Merge "Fallback to same-cell resize with qos ports" into stable/victoria22.1.0
6 files changed, 74 insertions, 32 deletions
diff --git a/api-guide/source/port_with_resource_request.rst b/api-guide/source/port_with_resource_request.rst index b09698c008..b5bb5bc491 100644 --- a/api-guide/source/port_with_resource_request.rst +++ b/api-guide/source/port_with_resource_request.rst @@ -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. diff --git a/doc/source/admin/configuration/cross-cell-resize.rst b/doc/source/admin/configuration/cross-cell-resize.rst index 8a82b60417..d17ee24109 100644 --- a/doc/source/admin/configuration/cross-cell-resize.rst +++ b/doc/source/admin/configuration/cross-cell-resize.rst @@ -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. diff --git a/nova/compute/api.py b/nova/compute/api.py index 56964c5e05..5568d39b22 100644 --- a/nova/compute/api.py +++ b/nova/compute/api.py @@ -3870,8 +3870,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. @@ -3879,8 +3878,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( @@ -3903,7 +3900,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 diff --git a/nova/tests/functional/test_servers.py b/nova/tests/functional/test_servers.py index 87a3a3a347..426745cb8a 100644 --- a/nova/tests/functional/test_servers.py +++ b/nova/tests/functional/test_servers.py @@ -8333,35 +8333,40 @@ 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 by not finding the target compute service - # in the same cell the source service. This is bug 1907511. If - # there would be a standalone fix for 1907511 then the next failure - # would be 1907522. Our coming fix will fix both bug with a same - # fix. self.api.post_server_action(server['id'], {'migrate': None}) self._wait_for_migration_status(server, ['error']) - self._wait_for_action_fail_completion( + self._wait_for_server_parameter( + server, + {'status': 'ACTIVE', 'OS-EXT-SRV-ATTR:host': 'host1'}) + event = self._wait_for_action_fail_completion( server, 'migrate', 'conductor_migrate_server') - # This is the root case self.assertIn( + 'exception.NoValidHost', event['traceback']) + log = self.stdlog.logger.output + 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.', + log) + self.assertNotIn( + 'nova.exception.PortBindingFailed: Binding failed for port', + log) + self.assertNotIn( "AttributeError: 'NoneType' object has no attribute 'version'", - self.stdlog.logger.output) + log) # 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) diff --git a/nova/tests/unit/compute/test_api.py b/nova/tests/unit/compute/test_api.py index 88dd94ac70..f151125b34 100644 --- a/nova/tests/unit/compute/test_api.py +++ b/nova/tests/unit/compute/test_api.py @@ -7522,28 +7522,54 @@ 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)) + can.assert_called_once() + 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_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): + 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): diff --git a/releasenotes/notes/cros-scell-resize-not-supported-with-ports-having-resource-request-a8e1029ef5983793.yaml b/releasenotes/notes/cros-scell-resize-not-supported-with-ports-having-resource-request-a8e1029ef5983793.yaml index 678eddcebd..31498a9d9c 100644 --- a/releasenotes/notes/cros-scell-resize-not-supported-with-ports-having-resource-request-a8e1029ef5983793.yaml +++ b/releasenotes/notes/cros-scell-resize-not-supported-with-ports-having-resource-request-a8e1029ef5983793.yaml @@ -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. |