]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
pybind/mgr/volumes: wire up charmap for subvol/subvolgroup
authorPatrick Donnelly <pdonnell@ibm.com>
Wed, 8 Jan 2025 14:51:32 +0000 (09:51 -0500)
committerPatrick Donnelly <pdonnell@ibm.com>
Fri, 28 Feb 2025 00:55:46 +0000 (19:55 -0500)
Signed-off-by: Patrick Donnelly <pdonnell@ibm.com>
src/pybind/mgr/volumes/fs/operations/charmap_util.py [new file with mode: 0644]
src/pybind/mgr/volumes/fs/operations/group.py
src/pybind/mgr/volumes/fs/operations/template.py
src/pybind/mgr/volumes/fs/operations/versions/subvolume_base.py
src/pybind/mgr/volumes/fs/volume.py
src/pybind/mgr/volumes/module.py

diff --git a/src/pybind/mgr/volumes/fs/operations/charmap_util.py b/src/pybind/mgr/volumes/fs/operations/charmap_util.py
new file mode 100644 (file)
index 0000000..8051b18
--- /dev/null
@@ -0,0 +1,58 @@
+import errno
+
+import cephfs
+
+from ..exception import VolumeException
+from ceph.utils import strtobool
+
+_charmap_type = {
+    "casesensitive": lambda x: int(strtobool(x)),
+    "normalization": lambda x: str(x),
+    "encoding": lambda x: str(x),
+}
+
+def charmap_set(fs, path, setting, value):
+    """
+    Set and get a charmap on a directory.
+    """
+
+    if setting not in _charmap_type:
+        raise VolumeException(-errno.EINVAL, f"charmap setting invalid")
+
+    try:
+        value = _charmap_type[setting](value)
+    except ValueError:
+        raise VolumeException(-errno.EINVAL, f"charmap value wrong type: {setting}")
+
+    try:
+        fs.setxattr(path, f"ceph.dir.{setting}", str(value).encode('utf-8'), 0)
+    except cephfs.Error as e:
+        raise VolumeException(-e.args[0], e.args[1])
+
+    try:
+        return fs.getxattr(path, f"ceph.dir.charmap").decode('utf-8')
+    except cephfs.Error as e:
+        raise VolumeException(-e.args[0], e.args[1])
+
+def charmap_rm(fs, path):
+    """
+    Remove a charmap on a directory.
+    """
+
+    try:
+        fs.removexattr(path, "ceph.dir.charmap", 0)
+    except cephfs.Error as e:
+        raise VolumeException(-e.args[0], e.args[1])
+
+def charmap_get(fs, path, setting):
+    """
+    Get a charmap on a directory.
+    """
+
+    if setting not in _charmap_type and setting != 'charmap':
+        raise VolumeException(-errno.EINVAL, f"charmap setting invalid")
+
+    try:
+        return fs.getxattr(path, f"ceph.dir.{setting}").decode('utf-8')
+    except cephfs.Error as e:
+        raise VolumeException(-e.args[0], e.args[1])
index efc10e0797aa29377b469bef3105261787f27562..60a734d942a79801c4de5a92d0cbc7820ce57e1c 100644 (file)
@@ -6,6 +6,7 @@ from contextlib import contextmanager
 import cephfs
 
 from .snapshot_util import mksnap, rmsnap
+from .charmap_util import charmap_get, charmap_set, charmap_rm
 from .pin_util import pin
 from .template import GroupTemplate
 from ..fs_util import listdir, listsnaps, get_ancestor_xattr, create_base_dir, has_subdir
@@ -78,6 +79,15 @@ class Group(GroupTemplate):
     def pin(self, pin_type, pin_setting):
         return pin(self.fs, self.path, pin_type, pin_setting)
 
+    def charmap_set(self, setting, value):
+        return charmap_set(self.fs, self.path, setting, value)
+
+    def charmap_rm(self):
+        return charmap_rm(self.fs, self.path)
+
+    def charmap_get(self, setting):
+        return charmap_get(self.fs, self.path, setting)
+
     def create_snapshot(self, snapname):
         snappath = os.path.join(self.path,
                                 self.vol_spec.snapshot_dir_prefix.encode('utf-8'),
index 2436863fd17985a0f89fb64ab4cfb3415ad3bc1c..171363e8fd282560e5ed6bf727114f8e8d789020 100644 (file)
@@ -40,6 +40,7 @@ class SubvolumeOpType(Enum):
     CREATE                = 'create'
     REMOVE                = 'rm'
     REMOVE_FORCE          = 'rm-force'
+    CHARMAP               = 'charmap'
     PIN                   = 'pin'
     LIST                  = 'ls'
     GETPATH               = 'getpath'
index 75382a1ca7eaba5de485f96bd74fae26a775a21b..bffaca156cf79ca8f1fe5b7b902c90f6f297781a 100644 (file)
@@ -9,6 +9,7 @@ from pathlib import Path
 
 import cephfs
 
+from ..charmap_util import charmap_get, charmap_set, charmap_rm
 from ..pin_util import pin
 from .subvolume_attrs import SubvolumeTypes
 from .metadata_manager import MetadataManager
@@ -342,6 +343,15 @@ class SubvolumeBase(object):
     def pin(self, pin_type, pin_setting):
         return pin(self.fs, self.base_path, pin_type, pin_setting)
 
+    def charmap_set(self, setting, value):
+        return charmap_set(self.fs, self.path, setting, value)
+
+    def charmap_rm(self):
+        return charmap_rm(self.fs, self.path)
+
+    def charmap_get(self, setting):
+        return charmap_get(self.fs, self.path, setting)
+
     def init_config(self, version, subvolume_type,
                     subvolume_path, subvolume_state):
         self.metadata_mgr.init(version, subvolume_type.value,
index 9679e171e8d2672bda6857788385e8b3ddbf1a57..af3fa29a40f490f14998296bcb3aa6c558d19b07 100644 (file)
@@ -423,6 +423,58 @@ class VolumeClient(CephfsClient["Module"]):
             ret = self.volume_exception_to_retval(ve)
         return ret
 
+    def subvolume_charmap_set(self, **kwargs):
+        ret         = 0, "", ""
+        volname     = kwargs['vol_name']
+        subvolname  = kwargs['sub_name']
+        setting     = kwargs['setting']
+        value       = kwargs['value']
+        groupname   = kwargs['group_name']
+
+        try:
+            with open_volume(self, volname) as fs_handle:
+                with open_group(fs_handle, self.volspec, groupname) as group:
+                    with open_subvol(self.mgr, fs_handle, self.volspec, group, subvolname, SubvolumeOpType.CHARMAP) as subvolume:
+                        v = subvolume.charmap_set(setting, value)
+                        ret = 0, v, ""
+        except VolumeException as ve:
+            ret = self.volume_exception_to_retval(ve)
+        return ret
+
+    def subvolume_charmap_rm(self, **kwargs):
+        ret         = 0, "", ""
+        volname     = kwargs['vol_name']
+        subvolname  = kwargs['sub_name']
+        groupname   = kwargs['group_name']
+
+        try:
+            with open_volume(self, volname) as fs_handle:
+                with open_group(fs_handle, self.volspec, groupname) as group:
+                    with open_subvol(self.mgr, fs_handle, self.volspec, group, subvolname, SubvolumeOpType.CHARMAP) as subvolume:
+                        subvolume.charmap_rm()
+                        ret = 0, json.dumps({}), ""
+        except VolumeException as ve:
+            ret = self.volume_exception_to_retval(ve)
+        return ret
+
+
+    def subvolume_charmap_get(self, **kwargs):
+        ret         = 0, "", ""
+        volname     = kwargs['vol_name']
+        subvolname  = kwargs['sub_name']
+        setting     = kwargs['setting']
+        groupname   = kwargs['group_name']
+
+        try:
+            with open_volume(self, volname) as fs_handle:
+                with open_group(fs_handle, self.volspec, groupname) as group:
+                    with open_subvol(self.mgr, fs_handle, self.volspec, group, subvolname, SubvolumeOpType.CHARMAP) as subvolume:
+                        v = subvolume.charmap_get(setting)
+                        ret = 0, v, ""
+        except VolumeException as ve:
+            ret = self.volume_exception_to_retval(ve)
+        return ret
+
     def subvolume_getpath(self, **kwargs):
         ret        = None
         volname    = kwargs['vol_name']
@@ -1131,6 +1183,51 @@ class VolumeClient(CephfsClient["Module"]):
             ret = self.volume_exception_to_retval(ve)
         return ret
 
+    def subvolume_group_charmap_set(self, **kwargs):
+        ret           = 0, "", ""
+        volname       = kwargs['vol_name']
+        groupname     = kwargs['group_name']
+        setting       = kwargs['setting']
+        value         = kwargs['value']
+
+        try:
+            with open_volume(self, volname) as fs_handle:
+                with open_group(fs_handle, self.volspec, groupname) as group:
+                    v = group.charmap_set(setting, value)
+                    ret = 0, v, ""
+        except VolumeException as ve:
+            ret = self.volume_exception_to_retval(ve)
+        return ret
+
+    def subvolume_group_charmap_rm(self, **kwargs):
+        ret           = 0, "", ""
+        volname       = kwargs['vol_name']
+        groupname     = kwargs['group_name']
+
+        try:
+            with open_volume(self, volname) as fs_handle:
+                with open_group(fs_handle, self.volspec, groupname) as group:
+                    group.charmap_rm()
+                    ret = 0, json.dumps({}), ""
+        except VolumeException as ve:
+            ret = self.volume_exception_to_retval(ve)
+        return ret
+
+    def subvolume_group_charmap_get(self, **kwargs):
+        ret           = 0, "", ""
+        volname       = kwargs['vol_name']
+        groupname     = kwargs['group_name']
+        setting       = kwargs['setting']
+
+        try:
+            with open_volume(self, volname) as fs_handle:
+                with open_group(fs_handle, self.volspec, groupname) as group:
+                    v = group.charmap_get(setting)
+                    ret = 0, v, ""
+        except VolumeException as ve:
+            ret = self.volume_exception_to_retval(ve)
+        return ret
+
     def subvolume_group_exists(self, **kwargs):
         volname = kwargs['vol_name']
         ret = 0, "", ""
index 6d768457f19b685fdc88b0397a6dc42e30aa6b2f..e8694709c530668463865052ddf66ce1241d074c 100644 (file)
@@ -331,6 +331,31 @@ class Module(orchestrator.OrchestratorClientMixin, MgrModule):
             'desc': "Set MDS pinning policy for subvolumegroup",
             'perm': 'rw'
         },
+        {
+            'cmd': 'fs subvolumegroup charmap set'
+                   ' name=vol_name,type=CephString'
+                   ' name=group_name,type=CephString,req=true'
+                   ' name=setting,type=CephChoices,strings=casesensitive|normalization|encoding'
+                   ' name=value,type=CephString,req=true',
+            'desc': "Set charmap settings for subvolumegroup",
+            'perm': 'rw'
+        },
+        {
+            'cmd': 'fs subvolumegroup charmap rm'
+                   ' name=vol_name,type=CephString'
+                   ' name=group_name,type=CephString,req=true',
+            'desc': "Remove charmap settings for subvolumegroup",
+            'perm': 'rw'
+        },
+        {
+            'cmd': 'fs subvolumegroup charmap get'
+                   ' name=vol_name,type=CephString'
+                   ' name=group_name,type=CephString,req=true'
+                   ' name=setting,type=CephChoices,strings=casesensitive|normalization|encoding,req=false',
+            'desc': "Get charmap settings for subvolumegroup",
+            'perm': 'rw'
+        },
+
         {
             'cmd': 'fs subvolumegroup snapshot ls '
                    'name=vol_name,type=CephString '
@@ -459,6 +484,33 @@ class Module(orchestrator.OrchestratorClientMixin, MgrModule):
             'desc': "Set MDS pinning policy for subvolume",
             'perm': 'rw'
         },
+        {
+            'cmd': 'fs subvolume charmap set'
+                   ' name=vol_name,type=CephString'
+                   ' name=sub_name,type=CephString'
+                   ' name=setting,type=CephChoices,strings=casesensitive|normalization|encoding'
+                   ' name=value,type=CephString,req=true'
+                   ' name=group_name,type=CephString,req=false',
+            'desc': "Set charmap settings for subvolumegroup",
+            'perm': 'rw'
+        },
+        {
+            'cmd': 'fs subvolume charmap rm'
+                   ' name=vol_name,type=CephString'
+                   ' name=sub_name,type=CephString'
+                   ' name=group_name,type=CephString,req=false',
+            'desc': "Remove charmap settings for subvolume",
+            'perm': 'rw'
+        },
+        {
+            'cmd': 'fs subvolume charmap get'
+                   ' name=vol_name,type=CephString'
+                   ' name=sub_name,type=CephString'
+                   ' name=setting,type=CephChoices,strings=casesensitive|normalization|encoding,req=false'
+                   ' name=group_name,type=CephString,req=false',
+            'desc': "Get charmap settings for subvolumegroup",
+            'perm': 'rw'
+        },
         {
             'cmd': 'fs subvolume snapshot protect '
                    'name=vol_name,type=CephString '
@@ -820,6 +872,23 @@ class Module(orchestrator.OrchestratorClientMixin, MgrModule):
                                            group_name=cmd['group_name'], pin_type=cmd['pin_type'],
                                            pin_setting=cmd['pin_setting'])
 
+    @mgr_cmd_wrap
+    def _cmd_fs_subvolumegroup_charmap_set(self, inbuf, cmd):
+        return self.vc.subvolume_group_charmap_set(vol_name=cmd['vol_name'],
+                                                   group_name=cmd['group_name'],
+                                                   setting=cmd['setting'],
+                                                   value=cmd['value'])
+    @mgr_cmd_wrap
+    def _cmd_fs_subvolumegroup_charmap_rm(self, inbuf, cmd):
+        return self.vc.subvolume_group_charmap_rm(vol_name=cmd['vol_name'],
+                                                   group_name=cmd['group_name'])
+
+    @mgr_cmd_wrap
+    def _cmd_fs_subvolumegroup_charmap_get(self, inbuf, cmd):
+        return self.vc.subvolume_group_charmap_get(vol_name=cmd['vol_name'],
+                                                   group_name=cmd['group_name'],
+                                                   setting=cmd.get('setting', 'charmap'))
+
     @mgr_cmd_wrap
     def _cmd_fs_subvolumegroup_snapshot_create(self, inbuf, cmd):
         return self.vc.create_subvolume_group_snapshot(vol_name=cmd['vol_name'],
@@ -912,6 +981,27 @@ class Module(orchestrator.OrchestratorClientMixin, MgrModule):
                                      pin_setting=cmd['pin_setting'],
                                      group_name=cmd.get('group_name', None))
 
+    @mgr_cmd_wrap
+    def _cmd_fs_subvolume_charmap_set(self, inbuf, cmd):
+        return self.vc.subvolume_charmap_set(vol_name=cmd['vol_name'],
+                                             sub_name=cmd['sub_name'],
+                                             setting=cmd['setting'],
+                                             value=cmd['value'],
+                                             group_name=cmd.get('group_name', None))
+
+    @mgr_cmd_wrap
+    def _cmd_fs_subvolume_charmap_rm(self, inbuf, cmd):
+        return self.vc.subvolume_charmap_rm(vol_name=cmd['vol_name'],
+                                             sub_name=cmd['sub_name'],
+                                             group_name=cmd.get('group_name', None))
+
+    @mgr_cmd_wrap
+    def _cmd_fs_subvolume_charmap_get(self, inbuf, cmd):
+        return self.vc.subvolume_charmap_get(vol_name=cmd['vol_name'],
+                                             sub_name=cmd['sub_name'],
+                                             setting=cmd.get('setting', 'charmap'),
+                                             group_name=cmd.get('group_name', None))
+
     @mgr_cmd_wrap
     def _cmd_fs_subvolume_snapshot_protect(self, inbuf, cmd):
         return self.vc.protect_subvolume_snapshot(vol_name=cmd['vol_name'], sub_name=cmd['sub_name'],