From 179e00207688285e282103994967b22f3b5852ca Mon Sep 17 00:00:00 2001 From: aticig Date: Tue, 29 Mar 2022 13:15:45 +0300 Subject: [PATCH] Fix Bug 1911 Root disk cannot be a Persistent Volume By this fix, VNFs could have persistent root disk if the disk type is defined as persistent-storage. Besides, the problem of creating unnecessary empty persistent volume is solved. Change-Id: Id032701bba4ce71080c338bc7f112261ec98861e Signed-off-by: aticig --- NG-RO/osm_ng_ro/ns.py | 34 ++- NG-RO/osm_ng_ro/tests/test_ns.py | 204 +++++++++++++++++- .../osm_rovim_openstack/vimconn_openstack.py | 5 + .../notes/fix_bug_1911-edf103cbb908f3ff.yaml | 23 ++ 4 files changed, 257 insertions(+), 9 deletions(-) create mode 100644 releasenotes/notes/fix_bug_1911-edf103cbb908f3ff.yaml diff --git a/NG-RO/osm_ng_ro/ns.py b/NG-RO/osm_ng_ro/ns.py index df5dfd21..e7291ea7 100644 --- a/NG-RO/osm_ng_ro/ns.py +++ b/NG-RO/osm_ng_ro/ns.py @@ -1069,14 +1069,34 @@ class Ns(object): if ssh_keys: cloud_config["key-pairs"] = ssh_keys - disk_list = None + persistent_root_disk = {} + disk_list = [] + vnfd_id = vnfr["vnfd-id"] + vnfd = db.get_one("vnfds", {"_id": vnfd_id}) + for vdu in vnfd.get("vdu", ()): + if vdu["name"] == target_vdu["vdu-name"]: + for vsd in vnfd.get("virtual-storage-desc", ()): + if vsd.get("id") == vdu.get("virtual-storage-desc", [[]])[0]: + root_disk = vsd + if root_disk.get( + "type-of-storage" + ) == "persistent-storage:persistent-storage" and root_disk.get( + "size-of-storage" + ): + persistent_root_disk[vsd["id"]] = { + "image_id": vdu.get("sw-image-desc"), + "size": root_disk["size-of-storage"], + } + disk_list.append(persistent_root_disk[vsd["id"]]) + if target_vdu.get("virtual-storages"): - disk_list = [ - {"size": disk["size-of-storage"]} - for disk in target_vdu["virtual-storages"] - if disk.get("type-of-storage") - == "persistent-storage:persistent-storage" - ] + for disk in target_vdu["virtual-storages"]: + if ( + disk.get("type-of-storage") + == "persistent-storage:persistent-storage" + and disk["id"] not in persistent_root_disk.keys() + ): + disk_list.append({"size": disk["size-of-storage"]}) affinity_group_list = [] diff --git a/NG-RO/osm_ng_ro/tests/test_ns.py b/NG-RO/osm_ng_ro/tests/test_ns.py index bcd5d46d..8c900b09 100644 --- a/NG-RO/osm_ng_ro/tests/test_ns.py +++ b/NG-RO/osm_ng_ro/tests/test_ns.py @@ -2457,8 +2457,208 @@ class TestNs(unittest.TestCase): def test__process_vdu_params_vdu_ssh_access_required(self): pass - def test__process_vdu_params_vdu_virtual_storages(self): - pass + @patch("osm_ng_ro.ns.Ns._get_cloud_init") + @patch("osm_ng_ro.ns.Ns._parse_jinja2") + def test__process_vdu_params_vdu_persistent_root_volume( + self, get_cloud_init, parse_jinja2 + ): + db = MagicMock(name="database mock") + kwargs = { + "db": db, + "vdu2cloud_init": {}, + "vnfr": { + "vnfd-id": "ad6356e3-698c-43bf-9901-3aae9e9b9d18", + "member-vnf-index-ref": "vnf-several-volumes", + }, + } + get_cloud_init.return_value = {} + parse_jinja2.return_value = {} + db.get_one.return_value = { + "_id": "ad6356e3-698c-43bf-9901-3aae9e9b9d18", + "df": [ + { + "id": "default-df", + "vdu-profile": [ + {"id": "several_volumes-VM", "min-number-of-instances": 1} + ], + } + ], + "id": "several_volumes-vnf", + "product-name": "several_volumes-vnf", + "vdu": [ + { + "id": "several_volumes-VM", + "name": "several_volumes-VM", + "sw-image-desc": "ubuntu20.04", + "alternative-sw-image-desc": [ + "ubuntu20.04-aws", + "ubuntu20.04-azure", + ], + "virtual-storage-desc": [ + "persistent-root-volume", + "persistent-volume2", + "ephemeral-volume", + ], + } + ], + "version": "1.0", + "virtual-storage-desc": [ + { + "id": "persistent-volume2", + "type-of-storage": "persistent-storage:persistent-storage", + "size-of-storage": "10", + }, + { + "id": "persistent-root-volume", + "type-of-storage": "persistent-storage:persistent-storage", + "size-of-storage": "10", + }, + { + "id": "ephemeral-volume", + "type-of-storage": "etsi-nfv-descriptors:ephemeral-storage", + "size-of-storage": "1", + }, + ], + "_admin": { + "storage": { + "fs": "mongo", + "path": "/app/storage/", + }, + "type": "vnfd", + }, + } + + target_vdu = { + "_id": "09a0baa7-b7cb-4924-bd63-9f04a1c23960", + "ns-flavor-id": "0", + "ns-image-id": "0", + "vdu-name": "several_volumes-VM", + "interfaces": [ + { + "name": "vdu-eth0", + "ns-vld-id": "mgmtnet", + } + ], + "virtual-storages": [ + { + "id": "persistent-volume2", + "size-of-storage": "10", + "type-of-storage": "persistent-storage:persistent-storage", + }, + { + "id": "persistent-root-volume", + "size-of-storage": "10", + "type-of-storage": "persistent-storage:persistent-storage", + }, + { + "id": "ephemeral-volume", + "size-of-storage": "1", + "type-of-storage": "etsi-nfv-descriptors:ephemeral-storage", + }, + ], + } + indata = { + "name": "sample_name", + } + expected_result = [{"image_id": "ubuntu20.04", "size": "10"}, {"size": "10"}] + result = Ns._process_vdu_params( + target_vdu, indata, vim_info=None, target_record_id=None, **kwargs + ) + self.assertEqual( + expected_result, result["params"]["disk_list"], "Wrong Disk List" + ) + + @patch("osm_ng_ro.ns.Ns._get_cloud_init") + @patch("osm_ng_ro.ns.Ns._parse_jinja2") + def test__process_vdu_params_vdu_without_persistent_storage( + self, get_cloud_init, parse_jinja2 + ): + db = MagicMock(name="database mock") + kwargs = { + "db": db, + "vdu2cloud_init": {}, + "vnfr": { + "vnfd-id": "ad6356e3-698c-43bf-9901-3aae9e9b9d18", + "member-vnf-index-ref": "vnf-several-volumes", + }, + } + get_cloud_init.return_value = {} + parse_jinja2.return_value = {} + db.get_one.return_value = { + "_id": "ad6356e3-698c-43bf-9901-3aae9e9b9d18", + "df": [ + { + "id": "default-df", + "vdu-profile": [ + {"id": "without_volumes-VM", "min-number-of-instances": 1} + ], + } + ], + "id": "without_volumes-vnf", + "product-name": "without_volumes-vnf", + "vdu": [ + { + "id": "without_volumes-VM", + "name": "without_volumes-VM", + "sw-image-desc": "ubuntu20.04", + "alternative-sw-image-desc": [ + "ubuntu20.04-aws", + "ubuntu20.04-azure", + ], + "virtual-storage-desc": ["root-volume", "ephemeral-volume"], + } + ], + "version": "1.0", + "virtual-storage-desc": [ + {"id": "root-volume", "size-of-storage": "10"}, + { + "id": "ephemeral-volume", + "type-of-storage": "etsi-nfv-descriptors:ephemeral-storage", + "size-of-storage": "1", + }, + ], + "_admin": { + "storage": { + "fs": "mongo", + "path": "/app/storage/", + }, + "type": "vnfd", + }, + } + + target_vdu = { + "_id": "09a0baa7-b7cb-4924-bd63-9f04a1c23960", + "ns-flavor-id": "0", + "ns-image-id": "0", + "vdu-name": "without_volumes-VM", + "interfaces": [ + { + "name": "vdu-eth0", + "ns-vld-id": "mgmtnet", + } + ], + "virtual-storages": [ + { + "id": "root-volume", + "size-of-storage": "10", + }, + { + "id": "ephemeral-volume", + "size-of-storage": "1", + "type-of-storage": "etsi-nfv-descriptors:ephemeral-storage", + }, + ], + } + indata = { + "name": "sample_name", + } + expected_result = [] + result = Ns._process_vdu_params( + target_vdu, indata, vim_info=None, target_record_id=None, **kwargs + ) + self.assertEqual( + expected_result, result["params"]["disk_list"], "Wrong Disk List" + ) def test__process_vdu_params(self): pass diff --git a/RO-VIM-openstack/osm_rovim_openstack/vimconn_openstack.py b/RO-VIM-openstack/osm_rovim_openstack/vimconn_openstack.py index a15a53cf..8f96f6b4 100644 --- a/RO-VIM-openstack/osm_rovim_openstack/vimconn_openstack.py +++ b/RO-VIM-openstack/osm_rovim_openstack/vimconn_openstack.py @@ -1867,6 +1867,7 @@ class vimconnector(vimconn.VimConnector): # Create additional volumes in case these are present in disk_list base_disk_index = ord("b") + boot_volume_id = None if disk_list: block_device_mapping = {} for disk in disk_list: @@ -1876,11 +1877,13 @@ class vimconnector(vimconn.VimConnector): ] else: if "image_id" in disk: + base_disk_index = ord("a") volume = self.cinder.volumes.create( size=disk["size"], name=name + "_vd" + chr(base_disk_index), imageRef=disk["image_id"], ) + boot_volume_id = volume.id else: volume = self.cinder.volumes.create( size=disk["size"], @@ -1912,6 +1915,8 @@ class vimconnector(vimconn.VimConnector): "Timeout creating volumes for instance " + name, http_code=vimconn.HTTP_Request_Timeout, ) + if boot_volume_id: + self.cinder.volumes.set_bootable(boot_volume_id, True) # get availability Zone vm_av_zone = self._get_vm_availability_zone( diff --git a/releasenotes/notes/fix_bug_1911-edf103cbb908f3ff.yaml b/releasenotes/notes/fix_bug_1911-edf103cbb908f3ff.yaml new file mode 100644 index 00000000..664b0322 --- /dev/null +++ b/releasenotes/notes/fix_bug_1911-edf103cbb908f3ff.yaml @@ -0,0 +1,23 @@ +####################################################################################### +# 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 1911 Root disk cannot be a Persistent Volume. VNFs could have + persistent root disk if the disk type is defined as persistent-storage. Besides, + the problem of creating one more persistent volume is solved. + -- 2.17.1