]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mgr/cephadm: nfs: shell out to rados tool for conf creation
authorSage Weil <sage@newdream.net>
Mon, 26 Apr 2021 18:54:38 +0000 (14:54 -0400)
committerSage Weil <sage@newdream.net>
Wed, 19 May 2021 12:43:14 +0000 (08:43 -0400)
This avoids any hangs due to rados.

Signed-off-by: Sage Weil <sage@newdream.net>
src/pybind/mgr/cephadm/services/nfs.py
src/pybind/mgr/cephadm/tests/test_cephadm.py

index 91fa3d5e5e9bbe309f7fae29cd3c1df8e9251331..72be22bafde96cfc0b5484af53c8757429c4c707 100644 (file)
@@ -8,7 +8,6 @@ from typing import Dict, Tuple, Any, List, cast, Optional
 from mgr_module import HandleCommandResult
 
 from ceph.deployment.service_spec import ServiceSpec, NFSServiceSpec
-import rados
 
 from orchestrator import DaemonDescription
 
@@ -138,24 +137,32 @@ class NFSService(CephService):
     def create_rados_config_obj(self,
                                 spec: NFSServiceSpec,
                                 clobber: bool = False) -> None:
-        with self.mgr.rados.open_ioctx(spec.pool) as ioctx:
-            if spec.namespace:
-                ioctx.set_namespace(spec.namespace)
-
-            obj = spec.rados_config_name()
-            exists = True
-            try:
-                ioctx.stat(obj)
-            except rados.ObjectNotFound:
-                exists = False
-
-            if exists and not clobber:
-                # Assume an existing config
-                logger.info('Rados config object exists: %s' % obj)
-            else:
-                # Create an empty config object
-                logger.info('Creating rados config object: %s' % obj)
-                ioctx.write_full(obj, ''.encode('utf-8'))
+        objname = spec.rados_config_name()
+        cmd = [
+            'rados',
+            '-n', f"mgr.{self.mgr.get_mgr_id()}",
+            '-k', str(self.mgr.get_ceph_option('keyring')),
+            '-p', cast(str, spec.pool),
+        ]
+        if spec.namespace:
+            cmd += ['--namespace', spec.namespace]
+        result = subprocess.run(
+            cmd + ['get', objname, '-'],
+            stdout=subprocess.PIPE, stderr=subprocess.PIPE,
+            timeout=10)
+        if not result.returncode and not clobber:
+            logger.info('Rados config object exists: %s' % objname)
+        else:
+            logger.info('Creating rados config object: %s' % objname)
+            result = subprocess.run(
+                cmd + ['put', objname, '-'],
+                stdout=subprocess.PIPE, stderr=subprocess.PIPE,
+                timeout=10)
+            if result.returncode:
+                self.mgr.log.warning(
+                    f'Unable to create rados config object {objname}: {result.stderr.decode("utf-8")}'
+                )
+                raise RuntimeError(result.stderr.decode("utf-8"))
 
     def create_keyring(self, daemon_spec: CephadmDaemonDeploySpec) -> str:
         daemon_id = daemon_spec.daemon_id
index 167fcc664b941ff7a9e786aff14660a2a7aa948d..18912fa4cc3e93d3ee00fd1f94cabfe187e6bf82 100644 (file)
@@ -755,7 +755,7 @@ class TestCephadm(object):
 
     @mock.patch("cephadm.serve.CephadmServe._run_cephadm", _run_cephadm('{}'))
     @mock.patch("cephadm.services.nfs.NFSService.run_grace_tool", mock.MagicMock())
-    @mock.patch("cephadm.module.CephadmOrchestrator.rados", mock.MagicMock())
+    @mock.patch("cephadm.services.nfs.NFSService.create_rados_config_obj", mock.MagicMock())
     def test_nfs(self, cephadm_module):
         with with_host(cephadm_module, 'test'):
             ps = PlacementSpec(hosts=['test'], count=1)
@@ -917,6 +917,7 @@ class TestCephadm(object):
     @mock.patch("subprocess.run", None)
     @mock.patch("cephadm.serve.CephadmServe._run_cephadm", _run_cephadm('{}'))
     @mock.patch("cephadm.services.nfs.NFSService.run_grace_tool", mock.MagicMock())
+    @mock.patch("cephadm.services.nfs.NFSService.create_rados_config_obj", mock.MagicMock())
     def test_apply_save(self, spec: ServiceSpec, meth, cephadm_module: CephadmOrchestrator):
         with with_host(cephadm_module, 'test'):
             with with_service(cephadm_module, spec, meth, 'test'):