From: Nizamudeen A Date: Thu, 9 Feb 2023 15:59:41 +0000 (+0530) Subject: mgr/dashboard: adapt nfs export code to the new changes in nfs module X-Git-Tag: v18.1.0~372^2 X-Git-Url: http://git.apps.os.sepia.ceph.com/?a=commitdiff_plain;h=dbcf28d462a8a3dc2b8709d1fc7af8df08c6694d;p=ceph.git mgr/dashboard: adapt nfs export code to the new changes in nfs module when you create/edit an nfs export from dashboard it leaves this traceback and error ``` Feb 09 14:15:54 ceph-node-00 ceph-mgr[3235]: [dashboard ERROR taskexec] Error while calling Task(ns=nfs/create, md={'path': 'e2e.nfs.bucket', 'fsal': 'RGW', 'cluster_id': 'testnfs'}) Traceback (most recent call last): File "/usr/share/ceph/mgr/dashboard/tools.py", line 550, in _run val = self.task.fn(*self.task.fn_args, **self.task.fn_kwargs) # type: ignore File "/usr/share/ceph/mgr/dashboard/controllers/nfs.py", line 148, in create ret, _, err = export_mgr.apply_export(cluster_id, json.dumps(raw_ex)) TypeError: 'AppliedExportResults' object is not iterable Feb 09 14:15:54 ceph-node-00 ceph-mgr[3235]: [dashboard INFO taskmgr] finished Task(ns=nfs/create, md={'path': 'e2e.nfs.bucket', 'fsal': 'RGW', 'cluster_id': 'testnfs'}) Feb 09 14:15:54 ceph-node-00 ceph-mgr[3235]: [dashboard INFO request] [::ffff:192.168.100.1:43896] [POST] [500] [0.767s] [admin] [172.0B] /api/nfs-ganesha/export ``` This started after https://github.com/ceph/ceph/pull/46209, so dashboard code needs to be adapted Fixes: https://tracker.ceph.com/issues/58681 Signed-off-by: Nizamudeen A --- diff --git a/src/pybind/mgr/dashboard/controllers/nfs.py b/src/pybind/mgr/dashboard/controllers/nfs.py index 5591a03c0ad75..36b88d76b165c 100644 --- a/src/pybind/mgr/dashboard/controllers/nfs.py +++ b/src/pybind/mgr/dashboard/controllers/nfs.py @@ -145,11 +145,11 @@ class NFSGaneshaExports(RESTController): 'fsal': fsal, 'clients': clients } - ret, _, err = export_mgr.apply_export(cluster_id, json.dumps(raw_ex)) - if ret == 0: + applied_exports = export_mgr.apply_export(cluster_id, json.dumps(raw_ex)) + if not applied_exports.has_error: return self._get_schema_export( export_mgr.get_export_by_pseudo(cluster_id, pseudo)) - raise NFSException(f"Export creation failed {err}") + raise NFSException(f"Export creation failed {applied_exports.changes[0].msg}") @EndpointDoc("Get an NFS-Ganesha export", parameters={ @@ -192,11 +192,11 @@ class NFSGaneshaExports(RESTController): } export_mgr = mgr.remote('nfs', 'fetch_nfs_export_obj') - ret, _, err = export_mgr.apply_export(cluster_id, json.dumps(raw_ex)) - if ret == 0: + applied_exports = export_mgr.apply_export(cluster_id, json.dumps(raw_ex)) + if not applied_exports.has_error: return self._get_schema_export( export_mgr.get_export_by_pseudo(cluster_id, pseudo)) - raise NFSException(f"Failed to update export: {err}") + raise NFSException(f"Export creation failed {applied_exports.changes[0].msg}") @NfsTask('delete', {'cluster_id': '{cluster_id}', 'export_id': '{export_id}'}, 2.0) diff --git a/src/pybind/mgr/dashboard/tests/test_nfs.py b/src/pybind/mgr/dashboard/tests/test_nfs.py index 5e71b6525c234..467d08a4c4e89 100644 --- a/src/pybind/mgr/dashboard/tests/test_nfs.py +++ b/src/pybind/mgr/dashboard/tests/test_nfs.py @@ -4,6 +4,8 @@ from copy import deepcopy from unittest.mock import Mock, patch from urllib.parse import urlencode +from nfs.export import AppliedExportResults + from .. import mgr from ..controllers._version import APIVersion from ..controllers.nfs import NFSGaneshaExports, NFSGaneshaUi @@ -36,6 +38,8 @@ class NFSGaneshaExportsTest(ControllerTestCase): "clients": [] } + _applied_export = AppliedExportResults() + @classmethod def setUpClass(cls): super().setUpClass() @@ -71,23 +75,24 @@ class NFSGaneshaExportsTest(ControllerTestCase): def test_create_export(self): export_mgr = Mock() created_nfs_export = deepcopy(self._nfs_module_export) + applied_nfs_export = deepcopy(self._applied_export) created_nfs_export['pseudo'] = 'new-pseudo' created_nfs_export['export_id'] = 2 export_mgr.get_export_by_pseudo.side_effect = [None, created_nfs_export] - export_mgr.apply_export.return_value = (0, '', '') + export_mgr.apply_export.return_value = applied_nfs_export mgr.remote.return_value = export_mgr export_create_body = deepcopy(self._expected_export) del export_create_body['export_id'] export_create_body['pseudo'] = created_nfs_export['pseudo'] + applied_nfs_export.append(export_create_body) self._post('/api/nfs-ganesha/export', export_create_body, version=APIVersion(2, 0)) self.assertStatus(201) - expected_body = export_create_body - expected_body['export_id'] = created_nfs_export['export_id'] - self.assertJsonBody(export_create_body) + applied_nfs_export.changes[0]['export_id'] = created_nfs_export['export_id'] + self.assertJsonBody(applied_nfs_export.changes[0]) def test_create_export_with_existing_pseudo_fails(self): export_mgr = Mock() @@ -108,19 +113,21 @@ class NFSGaneshaExportsTest(ControllerTestCase): def test_set_export(self): export_mgr = Mock() updated_nfs_export = deepcopy(self._nfs_module_export) + applied_nfs_export = deepcopy(self._applied_export) updated_nfs_export['pseudo'] = 'updated-pseudo' export_mgr.get_export_by_pseudo.return_value = updated_nfs_export - export_mgr.apply_export.return_value = (0, '', '') + export_mgr.apply_export.return_value = applied_nfs_export mgr.remote.return_value = export_mgr updated_export_body = deepcopy(self._expected_export) updated_export_body['pseudo'] = updated_nfs_export['pseudo'] + applied_nfs_export.append(updated_export_body) self._put('/api/nfs-ganesha/export/myc/2', updated_export_body, version=APIVersion(2, 0)) self.assertStatus(200) - self.assertJsonBody(updated_export_body) + self.assertJsonBody(applied_nfs_export.changes[0]) def test_delete_export(self): mgr.remote = Mock(side_effect=[self._nfs_module_export, None]) diff --git a/src/pybind/mgr/nfs/export.py b/src/pybind/mgr/nfs/export.py index 0496f9ed80f11..e6c514ecf5374 100644 --- a/src/pybind/mgr/nfs/export.py +++ b/src/pybind/mgr/nfs/export.py @@ -489,6 +489,8 @@ class ExportMgr: export = self._fetch_export(cluster_id, pseudo_path) return export.to_dict() if export else None + # This method is used by the dashboard module (../dashboard/controllers/nfs.py) + # Do not change interface without updating the Dashboard code def apply_export(self, cluster_id: str, export_config: str) -> AppliedExportResults: try: exports = self._read_export_config(cluster_id, export_config)