Bug 2180 fixed 99/12899/1
authorsritharan <priyadarshini@tataelxsi.co.in>
Thu, 13 Oct 2022 05:43:13 +0000 (05:43 +0000)
committergarciadeblas <gerardo.garciadeblas@telefonica.com>
Mon, 30 Jan 2023 16:43:52 +0000 (17:43 +0100)
Change-Id: Ib136760251c09cd803f2e313b184fa87428efd9b
Signed-off-by: sritharan <priyadarshini@tataelxsi.co.in>
Signed-off-by: garciadeblas <gerardo.garciadeblas@telefonica.com>
NG-RO/osm_ng_ro/ns.py
NG-RO/osm_ng_ro/tests/test_ns.py
RO-VIM-openstack/osm_rovim_openstack/vimconn_openstack.py
releasenotes/notes/fix_bug_2180-dd1ab93148aa4eb2.yaml [new file with mode: 0644]

index 1308fbd..f2e3405 100644 (file)
@@ -647,44 +647,57 @@ class Ns(object):
             Tuple[Dict[str, Any], bool]: [description]
         """
         numa = {}
+        numa_list = []
         epa_vcpu_set = False
 
         if guest_epa_quota.get("numa-node-policy"):
             numa_node_policy = guest_epa_quota.get("numa-node-policy")
 
             if numa_node_policy.get("node"):
-                numa_node = numa_node_policy["node"][0]
-
-                if numa_node.get("num-cores"):
-                    numa["cores"] = numa_node["num-cores"]
-                    epa_vcpu_set = True
-
-                paired_threads = numa_node.get("paired-threads", {})
-                if paired_threads.get("num-paired-threads"):
-                    numa["paired-threads"] = int(
-                        numa_node["paired-threads"]["num-paired-threads"]
-                    )
-                    epa_vcpu_set = True
+                for numa_node in numa_node_policy["node"]:
+                    vcpu_list = []
+                    if numa_node.get("id"):
+                        numa["id"] = int(numa_node["id"])
+
+                    if numa_node.get("vcpu"):
+                        for vcpu in numa_node.get("vcpu"):
+                            vcpu_id = int(vcpu.get("id"))
+                            vcpu_list.append(vcpu_id)
+                        numa["vcpu"] = vcpu_list
+
+                    if numa_node.get("num-cores"):
+                        numa["cores"] = numa_node["num-cores"]
+                        epa_vcpu_set = True
+
+                    paired_threads = numa_node.get("paired-threads", {})
+                    if paired_threads.get("num-paired-threads"):
+                        numa["paired_threads"] = int(
+                            numa_node["paired-threads"]["num-paired-threads"]
+                        )
+                        epa_vcpu_set = True
 
-                if paired_threads.get("paired-thread-ids"):
-                    numa["paired-threads-id"] = []
+                    if paired_threads.get("paired-thread-ids"):
+                        numa["paired-threads-id"] = []
 
-                    for pair in paired_threads["paired-thread-ids"]:
-                        numa["paired-threads-id"].append(
-                            (
-                                str(pair["thread-a"]),
-                                str(pair["thread-b"]),
+                        for pair in paired_threads["paired-thread-ids"]:
+                            numa["paired-threads-id"].append(
+                                (
+                                    str(pair["thread-a"]),
+                                    str(pair["thread-b"]),
+                                )
                             )
-                        )
 
-                if numa_node.get("num-threads"):
-                    numa["threads"] = int(numa_node["num-threads"])
-                    epa_vcpu_set = True
+                    if numa_node.get("num-threads"):
+                        numa["threads"] = int(numa_node["num-threads"])
+                        epa_vcpu_set = True
 
-                if numa_node.get("memory-mb"):
-                    numa["memory"] = max(int(int(numa_node["memory-mb"]) / 1024), 1)
+                    if numa_node.get("memory-mb"):
+                        numa["memory"] = max(int(int(numa_node["memory-mb"]) / 1024), 1)
 
-        return numa, epa_vcpu_set
+                    numa_list.append(numa)
+                    numa = {}
+
+        return numa_list, epa_vcpu_set
 
     @staticmethod
     def _process_guest_epa_cpu_pinning_params(
@@ -732,23 +745,39 @@ class Ns(object):
         """
         extended = {}
         numa = {}
+        numa_list = []
 
         if target_flavor.get("guest-epa"):
             guest_epa = target_flavor["guest-epa"]
 
-            numa, epa_vcpu_set = Ns._process_guest_epa_numa_params(
+            numa_list, epa_vcpu_set = Ns._process_guest_epa_numa_params(
                 guest_epa_quota=guest_epa
             )
 
             if guest_epa.get("mempage-size"):
                 extended["mempage-size"] = guest_epa.get("mempage-size")
 
+            if guest_epa.get("cpu-pinning-policy"):
+                extended["cpu-pinning-policy"] = guest_epa.get("cpu-pinning-policy")
+
+            if guest_epa.get("cpu-thread-pinning-policy"):
+                extended["cpu-thread-pinning-policy"] = guest_epa.get(
+                    "cpu-thread-pinning-policy"
+                )
+
+            if guest_epa.get("numa-node-policy"):
+                if guest_epa.get("numa-node-policy").get("mem-policy"):
+                    extended["mem-policy"] = guest_epa.get("numa-node-policy").get(
+                        "mem-policy"
+                    )
+
             tmp_numa, epa_vcpu_set = Ns._process_guest_epa_cpu_pinning_params(
                 guest_epa_quota=guest_epa,
                 vcpu_count=int(target_flavor.get("vcpu-count", 1)),
                 epa_vcpu_set=epa_vcpu_set,
             )
-            numa.update(tmp_numa)
+            for numa in numa_list:
+                numa.update(tmp_numa)
 
             extended.update(
                 Ns._process_guest_epa_quota_params(
@@ -758,7 +787,7 @@ class Ns(object):
             )
 
         if numa:
-            extended["numas"] = [numa]
+            extended["numas"] = numa_list
 
         return extended
 
index e69a4c5..af44850 100644 (file)
@@ -831,19 +831,18 @@ class TestNs(unittest.TestCase):
         self.assertDictEqual(expected_result, result)
 
     def test__process_guest_epa_numa_params_with_empty_numa_params(self):
-        expected_numa_result = {}
+        expected_numa_result = []
         expected_epa_vcpu_set_result = False
         guest_epa_quota = {}
 
         numa_result, epa_vcpu_set_result = Ns._process_guest_epa_numa_params(
             guest_epa_quota=guest_epa_quota,
         )
-
-        self.assertDictEqual(expected_numa_result, numa_result)
+        self.assertEqual(expected_numa_result, numa_result)
         self.assertEqual(expected_epa_vcpu_set_result, epa_vcpu_set_result)
 
     def test__process_guest_epa_numa_params_with_wrong_numa_params(self):
-        expected_numa_result = {}
+        expected_numa_result = []
         expected_epa_vcpu_set_result = False
         guest_epa_quota = {"no_nume": "here"}
 
@@ -851,11 +850,11 @@ class TestNs(unittest.TestCase):
             guest_epa_quota=guest_epa_quota,
         )
 
-        self.assertDictEqual(expected_numa_result, numa_result)
+        self.assertEqual(expected_numa_result, numa_result)
         self.assertEqual(expected_epa_vcpu_set_result, epa_vcpu_set_result)
 
     def test__process_guest_epa_numa_params_with_numa_node_policy(self):
-        expected_numa_result = {}
+        expected_numa_result = []
         expected_epa_vcpu_set_result = False
         guest_epa_quota = {"numa-node-policy": {}}
 
@@ -863,11 +862,11 @@ class TestNs(unittest.TestCase):
             guest_epa_quota=guest_epa_quota,
         )
 
-        self.assertDictEqual(expected_numa_result, numa_result)
+        self.assertEqual(expected_numa_result, numa_result)
         self.assertEqual(expected_epa_vcpu_set_result, epa_vcpu_set_result)
 
     def test__process_guest_epa_numa_params_with_no_node(self):
-        expected_numa_result = {}
+        expected_numa_result = []
         expected_epa_vcpu_set_result = False
         guest_epa_quota = {
             "numa-node-policy": {
@@ -879,11 +878,11 @@ class TestNs(unittest.TestCase):
             guest_epa_quota=guest_epa_quota,
         )
 
-        self.assertDictEqual(expected_numa_result, numa_result)
+        self.assertEqual(expected_numa_result, numa_result)
         self.assertEqual(expected_epa_vcpu_set_result, epa_vcpu_set_result)
 
     def test__process_guest_epa_numa_params_with_1_node_num_cores(self):
-        expected_numa_result = {"cores": 3}
+        expected_numa_result = [{"cores": 3}]
         expected_epa_vcpu_set_result = True
         guest_epa_quota = {
             "numa-node-policy": {
@@ -899,11 +898,11 @@ class TestNs(unittest.TestCase):
             guest_epa_quota=guest_epa_quota,
         )
 
-        self.assertDictEqual(expected_numa_result, numa_result)
+        self.assertEqual(expected_numa_result, numa_result)
         self.assertEqual(expected_epa_vcpu_set_result, epa_vcpu_set_result)
 
     def test__process_guest_epa_numa_params_with_1_node_paired_threads(self):
-        expected_numa_result = {"paired-threads": 3}
+        expected_numa_result = [{"paired_threads": 3}]
         expected_epa_vcpu_set_result = True
         guest_epa_quota = {
             "numa-node-policy": {
@@ -919,13 +918,15 @@ class TestNs(unittest.TestCase):
             guest_epa_quota=guest_epa_quota,
         )
 
-        self.assertDictEqual(expected_numa_result, numa_result)
+        self.assertEqual(expected_numa_result, numa_result)
         self.assertEqual(expected_epa_vcpu_set_result, epa_vcpu_set_result)
 
     def test__process_guest_epa_numa_params_with_1_node_paired_threads_ids(self):
-        expected_numa_result = {
-            "paired-threads-id": [("0", "1"), ("4", "5")],
-        }
+        expected_numa_result = [
+            {
+                "paired-threads-id": [("0", "1"), ("4", "5")],
+            }
+        ]
         expected_epa_vcpu_set_result = False
         guest_epa_quota = {
             "numa-node-policy": {
@@ -952,11 +953,11 @@ class TestNs(unittest.TestCase):
             guest_epa_quota=guest_epa_quota,
         )
 
-        self.assertDictEqual(expected_numa_result, numa_result)
+        self.assertEqual(expected_numa_result, numa_result)
         self.assertEqual(expected_epa_vcpu_set_result, epa_vcpu_set_result)
 
     def test__process_guest_epa_numa_params_with_1_node_num_threads(self):
-        expected_numa_result = {"threads": 3}
+        expected_numa_result = [{"threads": 3}]
         expected_epa_vcpu_set_result = True
         guest_epa_quota = {
             "numa-node-policy": {
@@ -972,11 +973,11 @@ class TestNs(unittest.TestCase):
             guest_epa_quota=guest_epa_quota,
         )
 
-        self.assertDictEqual(expected_numa_result, numa_result)
+        self.assertEqual(expected_numa_result, numa_result)
         self.assertEqual(expected_epa_vcpu_set_result, epa_vcpu_set_result)
 
     def test__process_guest_epa_numa_params_with_1_node_memory_mb(self):
-        expected_numa_result = {"memory": 2}
+        expected_numa_result = [{"memory": 2}]
         expected_epa_vcpu_set_result = False
         guest_epa_quota = {
             "numa-node-policy": {
@@ -992,17 +993,71 @@ class TestNs(unittest.TestCase):
             guest_epa_quota=guest_epa_quota,
         )
 
-        self.assertDictEqual(expected_numa_result, numa_result)
+        self.assertEqual(expected_numa_result, numa_result)
         self.assertEqual(expected_epa_vcpu_set_result, epa_vcpu_set_result)
 
-    def test__process_guest_epa_numa_params_with_1_node(self):
-        expected_numa_result = {
-            "cores": 3,
-            "paired-threads": 3,
-            "paired-threads-id": [("0", "1"), ("4", "5")],
-            "threads": 3,
-            "memory": 2,
+    def test__process_guest_epa_numa_params_with_1_node_vcpu(self):
+        expected_numa_result = [
+            {
+                "id": 0,
+                "vcpu": [0, 1],
+            }
+        ]
+        expected_epa_vcpu_set_result = False
+        guest_epa_quota = {
+            "numa-node-policy": {
+                "node": [{"id": "0", "vcpu": [{"id": "0"}, {"id": "1"}]}],
+            },
         }
+
+        numa_result, epa_vcpu_set_result = Ns._process_guest_epa_numa_params(
+            guest_epa_quota=guest_epa_quota,
+        )
+
+        self.assertEqual(expected_numa_result, numa_result)
+        self.assertEqual(expected_epa_vcpu_set_result, epa_vcpu_set_result)
+
+    def test__process_guest_epa_numa_params_with_2_node_vcpu(self):
+        expected_numa_result = [
+            {
+                "id": 0,
+                "vcpu": [0, 1],
+            },
+            {
+                "id": 1,
+                "vcpu": [2, 3],
+            },
+        ]
+
+        expected_epa_vcpu_set_result = False
+        guest_epa_quota = {
+            "numa-node-policy": {
+                "node": [
+                    {"id": "0", "vcpu": [{"id": "0"}, {"id": "1"}]},
+                    {"id": "1", "vcpu": [{"id": "2"}, {"id": "3"}]},
+                ],
+            },
+        }
+
+        numa_result, epa_vcpu_set_result = Ns._process_guest_epa_numa_params(
+            guest_epa_quota=guest_epa_quota,
+        )
+
+        self.assertEqual(expected_numa_result, numa_result)
+        self.assertEqual(expected_epa_vcpu_set_result, epa_vcpu_set_result)
+
+    def test__process_guest_epa_numa_params_with_1_node(self):
+        expected_numa_result = [
+            {
+                # "id": 0,
+                # "vcpu": [0, 1],
+                "cores": 3,
+                "paired_threads": 3,
+                "paired-threads-id": [("0", "1"), ("4", "5")],
+                "threads": 3,
+                "memory": 2,
+            }
+        ]
         expected_epa_vcpu_set_result = True
         guest_epa_quota = {
             "numa-node-policy": {
@@ -1033,17 +1088,26 @@ class TestNs(unittest.TestCase):
             guest_epa_quota=guest_epa_quota,
         )
 
-        self.assertDictEqual(expected_numa_result, numa_result)
+        self.assertEqual(expected_numa_result, numa_result)
         self.assertEqual(expected_epa_vcpu_set_result, epa_vcpu_set_result)
 
     def test__process_guest_epa_numa_params_with_2_nodes(self):
-        expected_numa_result = {
-            "cores": 3,
-            "paired-threads": 3,
-            "paired-threads-id": [("0", "1"), ("4", "5")],
-            "threads": 3,
-            "memory": 2,
-        }
+        expected_numa_result = [
+            {
+                "cores": 3,
+                "paired_threads": 3,
+                "paired-threads-id": [("0", "1"), ("4", "5")],
+                "threads": 3,
+                "memory": 2,
+            },
+            {
+                "cores": 7,
+                "paired_threads": 7,
+                "paired-threads-id": [("2", "3"), ("5", "6")],
+                "threads": 4,
+                "memory": 4,
+            },
+        ]
         expected_epa_vcpu_set_result = True
         guest_epa_quota = {
             "numa-node-policy": {
@@ -1092,7 +1156,7 @@ class TestNs(unittest.TestCase):
             guest_epa_quota=guest_epa_quota,
         )
 
-        self.assertDictEqual(expected_numa_result, numa_result)
+        self.assertEqual(expected_numa_result, numa_result)
         self.assertEqual(expected_epa_vcpu_set_result, epa_vcpu_set_result)
 
     def test__process_guest_epa_cpu_pinning_params_with_empty_params(self):
@@ -1237,10 +1301,15 @@ class TestNs(unittest.TestCase):
         guest_epa_cpu_pinning_params,
         guest_epa_quota_params,
     ):
-        expected_result = {}
+        expected_result = {
+            "mem-policy": "STRICT",
+        }
         target_flavor = {
             "guest-epa": {
                 "vcpu-count": 1,
+                "numa-node-policy": {
+                    "mem-policy": "STRICT",
+                },
             },
         }
 
@@ -1268,9 +1337,16 @@ class TestNs(unittest.TestCase):
     ):
         expected_result = {
             "mempage-size": "1G",
+            "mem-policy": "STRICT",
         }
         target_flavor = {
-            "guest-epa": {"vcpu-count": 1, "mempage-size": "1G"},
+            "guest-epa": {
+                "vcpu-count": 1,
+                "mempage-size": "1G",
+                "numa-node-policy": {
+                    "mem-policy": "STRICT",
+                },
+            },
         }
 
         guest_epa_numa_params.return_value = ({}, False)
@@ -1297,6 +1373,8 @@ class TestNs(unittest.TestCase):
     ):
         expected_result = {
             "mempage-size": "1G",
+            "cpu-pinning-policy": "DEDICATED",
+            "cpu-thread-pinning-policy": "PREFER",
             "numas": [
                 {
                     "cores": 3,
@@ -1363,13 +1441,15 @@ class TestNs(unittest.TestCase):
         }
 
         guest_epa_numa_params.return_value = (
-            {
-                "cores": 3,
-                "paired-threads": 3,
-                "paired-threads-id": [("0", "1"), ("4", "5")],
-                "threads": 3,
-                "memory": 2,
-            },
+            [
+                {
+                    "cores": 3,
+                    "paired-threads": 3,
+                    "paired-threads-id": [("0", "1"), ("4", "5")],
+                    "threads": 3,
+                    "memory": 2,
+                },
+            ],
             True,
         )
         guest_epa_cpu_pinning_params.return_value = (
@@ -1404,8 +1484,7 @@ class TestNs(unittest.TestCase):
         result = Ns._process_epa_params(
             target_flavor=target_flavor,
         )
-
-        self.assertDictEqual(expected_result, result)
+        self.assertEqual(expected_result, result)
         self.assertTrue(guest_epa_numa_params.called)
         self.assertTrue(guest_epa_cpu_pinning_params.called)
         self.assertTrue(guest_epa_quota_params.called)
index 934cde9..bbc8426 100644 (file)
@@ -1283,13 +1283,7 @@ class vimconnector(vimconn.VimConnector):
                         if numas:
                             numa_nodes = len(numas)
 
-                            if numa_nodes > 1:
-                                return -1, "Can not add flavor with more than one numa"
-
                             extra_specs["hw:numa_nodes"] = str(numa_nodes)
-                            extra_specs["hw:mem_page_size"] = "large"
-                            extra_specs["hw:cpu_policy"] = "dedicated"
-                            extra_specs["hw:numa_mempolicy"] = "strict"
 
                             if self.vim_type == "VIO":
                                 extra_specs[
@@ -1298,13 +1292,25 @@ class vimconnector(vimconn.VimConnector):
                                 extra_specs["vmware:latency_sensitivity_level"] = "high"
 
                             for numa in numas:
+                                if "id" in numa:
+                                    node_id = numa["id"]
+
+                                    if "memory" in numa:
+                                        memory_mb = numa["memory"] * 1024
+                                        memory = "hw:numa_mem.{}".format(node_id)
+                                        extra_specs[memory] = int(memory_mb)
+
+                                    if "vcpu" in numa:
+                                        vcpu = numa["vcpu"]
+                                        cpu = "hw:numa_cpus.{}".format(node_id)
+                                        vcpu = ",".join(map(str, vcpu))
+                                        extra_specs[cpu] = vcpu
+
                                 # overwrite ram and vcpus
                                 # check if key "memory" is present in numa else use ram value at flavor
-                                if "memory" in numa:
-                                    ram = numa["memory"] * 1024
                                 # See for reference: https://specs.openstack.org/openstack/nova-specs/specs/mitaka/
                                 # implemented/virt-driver-cpu-thread-pinning.html
-                                extra_specs["hw:cpu_sockets"] = 1
+                                extra_specs["hw:cpu_sockets"] = str(numa_nodes)
 
                                 if "paired-threads" in numa:
                                     vcpus = numa["paired-threads"] * 2
@@ -1369,6 +1375,23 @@ class vimconnector(vimconn.VimConnector):
                                     "Invalid mempage-size %s. Will be ignored",
                                     extended.get("mempage-size"),
                                 )
+                        if extended.get("cpu-pinning-policy"):
+                            extra_specs["hw:cpu_policy"] = extended.get(
+                                "cpu-pinning-policy"
+                            ).lower()
+
+                        # Set the cpu thread pinning policy as specified in the descriptor
+                        if extended.get("cpu-thread-pinning-policy"):
+                            extra_specs["hw:cpu_thread_policy"] = extended.get(
+                                "cpu-thread-pinning-policy"
+                            ).lower()
+
+                        # Set the mem policy as specified in the descriptor
+                        if extended.get("mem-policy"):
+                            extra_specs["hw:numa_mempolicy"] = extended.get(
+                                "mem-policy"
+                            ).lower()
+
                     # create flavor
                     new_flavor = self.nova.flavors.create(
                         name=name,
diff --git a/releasenotes/notes/fix_bug_2180-dd1ab93148aa4eb2.yaml b/releasenotes/notes/fix_bug_2180-dd1ab93148aa4eb2.yaml
new file mode 100644 (file)
index 0000000..2388637
--- /dev/null
@@ -0,0 +1,22 @@
+#######################################################################################
+# Copyright ETSI Contributors and Others.
+#
+# 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.
+#######################################################################################
+---
+fixes:
+  - |
+    This fixes the bug 2180.EPA will set only the parameters that are explicitly
+    defined in the vnfd descriptor.Numa policy supports for multiple nodes with numa 
+    cpus.