From a061b0ea2e7f13a71dcc0f088c9dae3b11ba7059 Mon Sep 17 00:00:00 2001 From: Balazs Gibizer Date: Wed, 4 Sep 2019 12:27:18 +0200 Subject: [PATCH] migrate: Add bw min service level check of source compute During cold migrate the RequestSpec goes from the dest compute to the source compute and then back to the dest. The previous patch [1] added service level check for the dest compute. However the source compute also needs to be new enough so the RequestSpec is passed through it. Please note that the functional coverage for this api change is in a later patch [2]. [1] https://review.opendev.org/#/c/680394 [2] https://review.opendev.org/#/c/655113 blueprint: support-move-ops-with-qos-ports Change-Id: I09cac780b9ee5b5726874d4e6f895fd0cd4bff8c --- nova/api/openstack/compute/migrate_server.py | 30 ++++++++++++++----- .../openstack/compute/test_migrate_server.py | 23 ++++++++++++++ 2 files changed, 45 insertions(+), 8 deletions(-) diff --git a/nova/api/openstack/compute/migrate_server.py b/nova/api/openstack/compute/migrate_server.py index 3a3f84158f..17c1975fa1 100644 --- a/nova/api/openstack/compute/migrate_server.py +++ b/nova/api/openstack/compute/migrate_server.py @@ -27,10 +27,13 @@ from nova.compute import api as compute from nova import exception from nova.i18n import _ from nova import network +from nova import objects from nova.policies import migrate_server as ms_policies LOG = logging.getLogger(__name__) +MIN_COMPUTE_MOVE_BANDWIDTH = 39 + class MigrateServerController(wsgi.Controller): def __init__(self): @@ -58,14 +61,25 @@ class MigrateServerController(wsgi.Controller): # We could potentially move this check to conductor and avoid the # extra API call to neutron when we support move operations with ports # having resource requests. - if (common.instance_has_port_with_resource_request( - context, instance.uuid, self.network_api) and not - common.supports_port_resource_request_during_move(req)): - msg = _("The migrate action on a server with ports having " - "resource requests, like a port with a QoS minimum " - "bandwidth policy, is not supported with this " - "microversion") - raise exc.HTTPBadRequest(explanation=msg) + if common.instance_has_port_with_resource_request( + context, instance.uuid, self.network_api): + if not common.supports_port_resource_request_during_move(req): + msg = _("The migrate action on a server with ports having " + "resource requests, like a port with a QoS minimum " + "bandwidth policy, is not supported with this " + "microversion") + raise exc.HTTPBadRequest(explanation=msg) + + # TODO(gibi): Remove when nova only supports compute newer than + # Train + source_service = objects.Service.get_by_host_and_binary( + context, instance.host, 'nova-compute') + if source_service.version < MIN_COMPUTE_MOVE_BANDWIDTH: + msg = _("The migrate action on a server with ports having " + "resource requests, like a port with a QoS " + "minimum bandwidth policy, is not yet supported " + "on the source compute") + raise exc.HTTPConflict(explanation=msg) try: self.compute_api.resize(req.environ['nova.context'], instance, diff --git a/nova/tests/unit/api/openstack/compute/test_migrate_server.py b/nova/tests/unit/api/openstack/compute/test_migrate_server.py index 916f9b16d2..dfc4638fde 100644 --- a/nova/tests/unit/api/openstack/compute/test_migrate_server.py +++ b/nova/tests/unit/api/openstack/compute/test_migrate_server.py @@ -296,6 +296,29 @@ class MigrateServerTestsV21(admin_only_action_common.CommonTests): expected_exc=webob.exc.HTTPInternalServerError, check_response=False) + @mock.patch('nova.api.openstack.common.' + 'supports_port_resource_request_during_move', + return_value=True) + @mock.patch('nova.objects.Service.get_by_host_and_binary') + @mock.patch('nova.api.openstack.common.' + 'instance_has_port_with_resource_request', return_value=True) + def test_migrate_with_bandwidth_from_old_compute_not_supported( + self, mock_has_res_req, mock_get_service, mock_support): + instance = self._stub_instance_get() + + mock_get_service.return_value = objects.Service(host=instance['host']) + mock_get_service.return_value.version = 38 + + self.assertRaises( + webob.exc.HTTPConflict, self.controller._migrate, self.req, + instance['uuid'], body={'migrate': None}) + + mock_has_res_req.assert_called_once_with( + self.req.environ['nova.context'], instance['uuid'], + self.controller.network_api) + mock_get_service.assert_called_once_with( + self.req.environ['nova.context'], instance['host'], 'nova-compute') + class MigrateServerTestsV225(MigrateServerTestsV21):