From 70ddf4eef579653c327067f05496f735970e7944 Mon Sep 17 00:00:00 2001 From: Rodolfo Alonso Hernandez Date: Sat, 24 Feb 2024 10:41:39 +0000 Subject: [PATCH] Add "socket" NUMA affinity policy This new extension adds a new parameter to the NUMA affinity policy list: "socket". The "socket" NUMA affinity policy has been supported in Nova since [1]. [1]https://review.opendev.org/c/openstack/nova/+/773792 Closes-Bug: #2052786 Change-Id: Iad2d4c461a2aceef6ed2d5e622cce38362d79687 --- neutron/common/ovn/extensions.py | 2 + .../175fa80908e1_add_numa_policy_socket.py | 39 +++++++++++ .../alembic_migrations/versions/EXPAND_HEAD | 2 +- .../port_numa_affinity_policy_socket.py | 20 ++++++ neutron/plugins/ml2/plugin.py | 3 + .../tests/contrib/hooks/api_all_extensions | 1 + .../test_port_numa_affinity_policy_socket.py | 69 +++++++++++++++++++ .../test_port_numa_affinity_policy.py | 6 +- 8 files changed, 138 insertions(+), 4 deletions(-) create mode 100644 neutron/db/migration/alembic_migrations/versions/2024.2/expand/175fa80908e1_add_numa_policy_socket.py create mode 100644 neutron/extensions/port_numa_affinity_policy_socket.py create mode 100644 neutron/tests/unit/extensions/test_port_numa_affinity_policy_socket.py diff --git a/neutron/common/ovn/extensions.py b/neutron/common/ovn/extensions.py index 0122e438e9d..e40e01c0c09 100644 --- a/neutron/common/ovn/extensions.py +++ b/neutron/common/ovn/extensions.py @@ -58,6 +58,7 @@ from neutron_lib.api.definitions import port_device_profile from neutron_lib.api.definitions import port_hardware_offload_type from neutron_lib.api.definitions import port_mac_address_regenerate from neutron_lib.api.definitions import port_numa_affinity_policy +from neutron_lib.api.definitions import port_numa_affinity_policy_socket from neutron_lib.api.definitions import port_resource_request from neutron_lib.api.definitions import port_security from neutron_lib.api.definitions import portbindings @@ -153,6 +154,7 @@ ML2_SUPPORTED_API_EXTENSIONS = [ port_hardware_offload_type.ALIAS, port_mac_address_regenerate.ALIAS, port_numa_affinity_policy.ALIAS, + port_numa_affinity_policy_socket.ALIAS, port_security.ALIAS, provider_net.ALIAS, port_resource_request.ALIAS, diff --git a/neutron/db/migration/alembic_migrations/versions/2024.2/expand/175fa80908e1_add_numa_policy_socket.py b/neutron/db/migration/alembic_migrations/versions/2024.2/expand/175fa80908e1_add_numa_policy_socket.py new file mode 100644 index 00000000000..0dcc7d7a0be --- /dev/null +++ b/neutron/db/migration/alembic_migrations/versions/2024.2/expand/175fa80908e1_add_numa_policy_socket.py @@ -0,0 +1,39 @@ +# Copyright 2024 OpenStack Foundation +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# + +from neutron_lib import constants +import sqlalchemy as sa + +from neutron.db import migration + + +# Add NUMA policy 'socket' +# +# Revision ID: 175fa80908e1 +# Revises: 0e6eff810791 +# Create Date: 2024-02-24 10:25:52.418502 + +# revision identifiers, used by Alembic. +revision = '175fa80908e1' +down_revision = '0e6eff810791' + +table = 'portnumaaffinitypolicies' +new_enum = sa.Enum(*constants.PORT_NUMA_POLICIES, + name='numa_affinity_policy') + + +def upgrade(): + migration.alter_enum_add_value(table, 'numa_affinity_policy', new_enum, + True) diff --git a/neutron/db/migration/alembic_migrations/versions/EXPAND_HEAD b/neutron/db/migration/alembic_migrations/versions/EXPAND_HEAD index 866b0a90a0c..ce6a554ab98 100644 --- a/neutron/db/migration/alembic_migrations/versions/EXPAND_HEAD +++ b/neutron/db/migration/alembic_migrations/versions/EXPAND_HEAD @@ -1 +1 @@ -0e6eff810791 +175fa80908e1 diff --git a/neutron/extensions/port_numa_affinity_policy_socket.py b/neutron/extensions/port_numa_affinity_policy_socket.py new file mode 100644 index 00000000000..d6512a87df8 --- /dev/null +++ b/neutron/extensions/port_numa_affinity_policy_socket.py @@ -0,0 +1,20 @@ +# Copyright (c) 2024 Red Hat, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +from neutron_lib.api.definitions import port_numa_affinity_policy_socket +from neutron_lib.api import extensions as api_extensions + + +class Port_numa_affinity_policy_socket(api_extensions.APIExtensionDescriptor): + api_definition = port_numa_affinity_policy_socket diff --git a/neutron/plugins/ml2/plugin.py b/neutron/plugins/ml2/plugin.py index d6d3ff9ec73..b8d0a77df73 100644 --- a/neutron/plugins/ml2/plugin.py +++ b/neutron/plugins/ml2/plugin.py @@ -47,6 +47,8 @@ from neutron_lib.api.definitions import port_hardware_offload_type as phot_def from neutron_lib.api.definitions import port_mac_address_override from neutron_lib.api.definitions import port_mac_address_regenerate from neutron_lib.api.definitions import port_numa_affinity_policy as pnap_def +from neutron_lib.api.definitions import port_numa_affinity_policy_socket as \ + pnaps_def from neutron_lib.api.definitions import port_security as psec from neutron_lib.api.definitions import portbindings from neutron_lib.api.definitions import portbindings_extended as pbe_ext @@ -241,6 +243,7 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2, stateful_security_group.ALIAS, addrgrp_def.ALIAS, pnap_def.ALIAS, + pnaps_def.ALIAS, pdp_def.ALIAS, quota_check_limit.ALIAS, port_mac_address_override.ALIAS, diff --git a/neutron/tests/contrib/hooks/api_all_extensions b/neutron/tests/contrib/hooks/api_all_extensions index ce58876ec86..e237666261b 100644 --- a/neutron/tests/contrib/hooks/api_all_extensions +++ b/neutron/tests/contrib/hooks/api_all_extensions @@ -63,6 +63,7 @@ NETWORK_API_EXTENSIONS+=",port-device-profile" NETWORK_API_EXTENSIONS+=",port-hardware-offload-type" NETWORK_API_EXTENSIONS+=",port-mac-address-regenerate" NETWORK_API_EXTENSIONS+=",port-numa-affinity-policy" +NETWORK_API_EXTENSIONS+=",port-numa-affinity-policy-socket" NETWORK_API_EXTENSIONS+=",port-security-groups-filtering" NETWORK_API_EXTENSIONS+=",segment" NETWORK_API_EXTENSIONS+=",segments-peer-subnet-host-routes" diff --git a/neutron/tests/unit/extensions/test_port_numa_affinity_policy_socket.py b/neutron/tests/unit/extensions/test_port_numa_affinity_policy_socket.py new file mode 100644 index 00000000000..6717c21658a --- /dev/null +++ b/neutron/tests/unit/extensions/test_port_numa_affinity_policy_socket.py @@ -0,0 +1,69 @@ +# Copyright (c) 2020 Red Hat, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +import ddt +from neutron_lib.api.definitions import port_numa_affinity_policy_socket as \ + apidef +from neutron_lib import constants + +from neutron.tests.unit.db import test_db_base_plugin_v2 +from neutron.tests.unit.extensions import test_port_numa_affinity_policy + + +TESTED_POLICIES = constants.PORT_NUMA_POLICIES + + +class PortNumaAffinityPolicySocketExtensionTestPlugin( + test_port_numa_affinity_policy. + PortNumaAffinityPolicyExtensionTestPlugin): + """Test plugin to mixin the port NUMA affinity policy socket extension.""" + supported_extension_aliases = [apidef.ALIAS] + + +@ddt.ddt +class PortNumaAffinityPolicySocketExtensionTestCase( + test_db_base_plugin_v2.NeutronDbPluginV2TestCase): + """Test API extension numa_affinity_policy_socket attributes.""" + + def setUp(self, *args): + plugin = ( + 'neutron.tests.unit.extensions.test_port_numa_affinity_policy_' + 'socket.PortNumaAffinityPolicySocketExtensionTestPlugin') + super().setUp(plugin=plugin) + + def _create_and_check_port_nap(self, numa_affinity_policy): + name = 'numa_affinity_policy' + keys = [('name', name), ('admin_state_up', True), + ('status', self.port_create_status), + ('numa_affinity_policy', numa_affinity_policy)] + with self.port(name=name, + numa_affinity_policy=numa_affinity_policy) as port: + for k, v in keys: + self.assertEqual(v, port['port'][k]) + return port + + def _update_and_check_port_nap(self, port, numa_affinity_policy): + data = {'port': {'numa_affinity_policy': numa_affinity_policy}} + req = self.new_update_request('ports', data, + port['port']['id']) + res = self.deserialize(self.fmt, req.get_response(self.api)) + self.assertEqual(numa_affinity_policy, + res['port']['numa_affinity_policy']) + + @ddt.data(*TESTED_POLICIES, None) + def test_create_and_update_port_numa_affinity_policy(self, + numa_affinity_policy): + port = self._create_and_check_port_nap(numa_affinity_policy) + for new_nap in (*TESTED_POLICIES, None): + self._update_and_check_port_nap(port, new_nap) diff --git a/neutron/tests/unit/objects/port/extensions/test_port_numa_affinity_policy.py b/neutron/tests/unit/objects/port/extensions/test_port_numa_affinity_policy.py index 4e7474bc6b1..2099ae7584a 100644 --- a/neutron/tests/unit/objects/port/extensions/test_port_numa_affinity_policy.py +++ b/neutron/tests/unit/objects/port/extensions/test_port_numa_affinity_policy.py @@ -12,9 +12,8 @@ # License for the specific language governing permissions and limitations # under the License. -from neutron_lib import constants - from neutron.objects.port.extensions import port_numa_affinity_policy +from neutron.tests import tools as test_tools from neutron.tests.unit.objects import test_base as obj_test_base from neutron.tests.unit import testlib_api @@ -33,6 +32,7 @@ class PortNumaAffinityPolicyDbObjectTestCase( def setUp(self): super(PortNumaAffinityPolicyDbObjectTestCase, self).setUp() + numa = test_tools.get_random_port_numa_affinity_policy() self.update_obj_fields( {'port_id': lambda: self._create_test_port_id(), - 'numa_affinity_policy': constants.PORT_NUMA_POLICY_PREFERRED}) + 'numa_affinity_policy': numa})