]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mgr/nfs: support managing exports without orchestration enabled
authorJohn Mulligan <jmulligan@redhat.com>
Sat, 29 Jan 2022 16:23:00 +0000 (11:23 -0500)
committerJohn Mulligan <jmulligan@redhat.com>
Wed, 23 Feb 2022 21:33:48 +0000 (16:33 -0500)
This change allows the `ceph nfs export ...` commands to function
without the entire mgr/nfs subsystem requiring orchestration to be
enabled.  When there's no orchestration available, the code falls back
to examining the namespaces in the ".nfs" rados pool to determine what
cluster_id values are valid.

This change does not add support for creating the rados objects and
namespace needed to manage a nfs cluster. As discussed with the
orchestration group on 2022-01-22, rook does not need the mgr module to
establish the namespace. So, for now, we'll defer the work needed to
create the namespace/objects when orchestration is disabled.

Fixes: https://tracker.ceph.com/issues/54043
Signed-off-by: John Mulligan <jmulligan@redhat.com>
src/pybind/mgr/nfs/export.py

index 85135760813bd1cf1505d553188a320fb2ad1cdb..bd7c6b4ede1bdd8a7005bc27e75d9f49ea4acc9d 100644 (file)
@@ -1,17 +1,29 @@
 import errno
 import json
 import logging
-from typing import List, Any, Dict, Tuple, Optional, TYPE_CHECKING, TypeVar, Callable, cast
+from typing import (
+    List,
+    Any,
+    Dict,
+    Tuple,
+    Optional,
+    TYPE_CHECKING,
+    TypeVar,
+    Callable,
+    Set,
+    cast)
 from os.path import normpath
 
-from rados import TimedOut, ObjectNotFound, Rados
+from rados import TimedOut, ObjectNotFound, Rados, LIBRADOS_ALL_NSPACES
 
+from orchestrator import NoOrchestrator
 from mgr_module import NFS_POOL_NAME as POOL_NAME, NFS_GANESHA_SUPPORTED_FSALS
 
 from .export_utils import GaneshaConfParser, Export, RawBlock, CephFSFSAL, RGWFSAL
 from .exception import NFSException, NFSInvalidOperation, FSNotFound, \
     ClusterNotFound
 from .utils import (
+    CONF_PREFIX,
     EXPORT_PREFIX,
     USER_CONF_PREFIX,
     export_obj_name,
@@ -37,7 +49,14 @@ def export_cluster_checker(func: FuncT) -> FuncT:
         """
         This method checks if cluster exists
         """
-        if kwargs['cluster_id'] not in available_clusters(export.mgr):
+        try:
+            clusters = set(available_clusters(export.mgr))
+        except NoOrchestrator:
+            clusters = nfs_rados_configs(export.mgr.rados)
+        cluster_id: str = kwargs['cluster_id']
+        log.debug("checking for %r in known nfs clusters: %r",
+                  cluster_id, clusters)
+        if cluster_id not in clusters:
             return -errno.ENOENT, "", "Cluster does not exist"
         return func(export, *args, **kwargs)
     return cast(FuncT, cluster_check)
@@ -138,6 +157,21 @@ class NFSRados:
         return False
 
 
+def nfs_rados_configs(rados: 'Rados', nfs_pool: str = POOL_NAME) -> Set[str]:
+    """Return a set of all the namespaces in the nfs_pool where nfs
+    configuration objects are found. The namespaces also correspond
+    to the cluster ids.
+    """
+    ns: Set[str] = set()
+    prefixes = (EXPORT_PREFIX, CONF_PREFIX, USER_CONF_PREFIX)
+    with rados.open_ioctx(nfs_pool) as ioctx:
+        ioctx.set_namespace(LIBRADOS_ALL_NSPACES)
+        for obj in ioctx.list_objects():
+            if obj.key.startswith(prefixes):
+                ns.add(obj.nspace)
+    return ns
+
+
 class ExportMgr:
     def __init__(
             self,