]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mgr/volumes: uid, gid for subvolume create and subvolumegroup create commands
authorJos Collin <jcollin@redhat.com>
Wed, 11 Sep 2019 09:57:42 +0000 (15:27 +0530)
committerJos Collin <jcollin@redhat.com>
Tue, 19 Nov 2019 15:58:01 +0000 (21:28 +0530)
Allow setting uid, gid for subvolume create and subvolumegroup create commands

Fixes: https://tracker.ceph.com/issues/40959
Signed-off-by: Jos Collin <jcollin@redhat.com>
(cherry picked from commit 63226a73c491c4fee7879113b381489bed169d44)

src/pybind/mgr/volumes/fs/subvolume.py
src/pybind/mgr/volumes/fs/volume.py
src/pybind/mgr/volumes/module.py

index 8f3c2b1ab5ef4c50428d92b0e9b7ab155acac160..9705a2473ae57bbca7a4354a8029eebf61268de6 100644 (file)
@@ -57,7 +57,8 @@ class SubVolume(object):
 
     ### basic subvolume operations
 
-    def create_subvolume(self, spec, size=None, namespace_isolated=True, mode=0o755, pool=None):
+    def create_subvolume(self, spec, size=None,  pool=None, namespace_isolated=True,
+                         uid=None, gid=None, mode=0o755):
         """
         Set up metadata, pools and auth for a subvolume.
 
@@ -66,8 +67,11 @@ class SubVolume(object):
 
         :param spec: subvolume path specification
         :param size: In bytes, or None for no size limit
-        :param namespace_isolated: If true, use separate RADOS namespace for this subvolume
         :param pool: the RADOS pool where the data objects of the subvolumes will be stored
+        :param namespace_isolated: If true, use separate RADOS namespace for this subvolume
+        :param uid: the user identifier
+        :param gid: the group identifier
+        :mode: the user permissions
         :return: None
         """
         subvolpath = spec.subvolume_path
@@ -101,6 +105,23 @@ class SubVolume(object):
                 xattr_val = self._get_ancestor_xattr(subvolpath, "ceph.dir.layout.pool")
             # TODO: handle error...
             self.fs.setxattr(subvolpath, xattr_key, xattr_val.encode('utf-8'), 0)
+
+            groupstat = self.fs.stat(spec.group_path)
+            if uid is None:
+                uid = int(groupstat.st_uid)
+            elif uid < 0:
+                raise VolumeException(-errno.EINVAL, "Provide a valid uid")
+
+            if gid is None:
+                gid = int(groupstat.st_gid)
+            elif gid < 0:
+                raise VolumeException(-errno.EINVAL, "Provide a valid gid")
+
+            try:
+                self.fs.chown(subvolpath, uid, gid)
+            except cephfs.InvalidValue:
+                raise VolumeException(-e.args[0], e.args[1])
+
         except Exception as e:
             try:
                 # cleanup subvol path on best effort basis
@@ -212,7 +233,17 @@ class SubVolume(object):
 
     ### group operations
 
-    def create_group(self, spec, mode=0o755, pool=None):
+    def create_group(self, spec, pool=None, uid=None, gid=None, mode=0o755):
+        """
+        Create a subvolume group.
+
+        :param spec: subvolume path specification
+        :param pool: the RADOS pool where the data objects of the subvolumes will be stored
+        :param uid: the user identifier
+        :param gid: the group identifier
+        :mode: the user permissions
+        :return: None
+        """
         path = spec.group_path
         self.fs.mkdirs(path, mode)
         try:
@@ -223,6 +254,22 @@ class SubVolume(object):
             except cephfs.InvalidValue:
                 raise VolumeException(-errno.EINVAL,
                                       "Invalid pool layout '{0}'. It must be a valid data pool".format(pool))
+
+            if uid is None:
+                uid = 0
+            elif uid < 0:
+                raise VolumeException(-errno.EINVAL, "Provide a valid uid")
+
+            if gid is None:
+                gid = 0
+            elif gid < 0:
+                raise VolumeException(-errno.EINVAL, "Provide a valid gid")
+
+            try:
+                self.fs.chown(path, uid, gid)
+            except cephfs.InvalidValue:
+                raise VolumeException(-e.args[0], e.args[1])
+
         except Exception as e:
             try:
                 # cleanup group path on best effort basis
index 83ba46ff4a29ffcffcf2f38e2361ab20259479b6..ef3e4c789faf722f334adf28c7b7482933fb6f03 100644 (file)
@@ -388,6 +388,8 @@ class VolumeClient(object):
         groupname  = kwargs['group_name']
         size       = kwargs['size']
         pool       = kwargs['pool_layout']
+        uid        = kwargs['uid']
+        gid        = kwargs['gid']
         mode       = kwargs['mode']
 
         try:
@@ -397,7 +399,7 @@ class VolumeClient(object):
                     raise VolumeException(
                         -errno.ENOENT, "Subvolume group '{0}' not found, create it with " \
                         "`ceph fs subvolumegroup create` before creating subvolumes".format(groupname))
-                sv.create_subvolume(spec, size, pool=pool, mode=self.octal_str_to_decimal_int(mode))
+                sv.create_subvolume(spec, size, pool=pool, uid=uid, gid=gid, mode=self.octal_str_to_decimal_int(mode))
         except VolumeException as ve:
             ret = self.volume_exception_to_retval(ve)
         return ret
@@ -551,13 +553,15 @@ class VolumeClient(object):
         volname   = kwargs['vol_name']
         groupname = kwargs['group_name']
         pool      = kwargs['pool_layout']
+        uid       = kwargs['uid']
+        gid       = kwargs['gid']
         mode      = kwargs['mode']
 
         try:
             # TODO: validate that subvol size fits in volume size
             with SubVolume(self.mgr, fs_handle) as sv:
                 spec = SubvolumeSpec("", groupname)
-                sv.create_group(spec, pool=pool, mode=self.octal_str_to_decimal_int(mode))
+                sv.create_group(spec, pool=pool, uid=uid, gid=gid, mode=self.octal_str_to_decimal_int(mode))
         except VolumeException as ve:
             ret = self.volume_exception_to_retval(ve)
         return ret
index 0e710cfd5fc46c9a2d883dafdfc360ea8a2ccdb1..aaf8691150e698b311c5b3fb8abf2c9077e2b9d9 100644 (file)
@@ -53,6 +53,8 @@ class Module(orchestrator.OrchestratorClientMixin, MgrModule):
                    'name=vol_name,type=CephString '
                    'name=group_name,type=CephString '
                    'name=pool_layout,type=CephString,req=false '
+                   'name=uid,type=CephInt,req=false '
+                   'name=gid,type=CephInt,req=false '
                    'name=mode,type=CephString,req=false ',
             'desc': "Create a CephFS subvolume group in a volume, and optionally, "
                     "with a specific data pool layout, and a specific numeric mode",
@@ -80,6 +82,8 @@ class Module(orchestrator.OrchestratorClientMixin, MgrModule):
                    'name=size,type=CephInt,req=false '
                    'name=group_name,type=CephString,req=false '
                    'name=pool_layout,type=CephString,req=false '
+                   'name=uid,type=CephInt,req=false '
+                   'name=gid,type=CephInt,req=false '
                    'name=mode,type=CephString,req=false ',
             'desc': "Create a CephFS subvolume in a volume, and optionally, "
                     "with a specific size (in bytes), a specific data pool layout, "
@@ -235,7 +239,8 @@ class Module(orchestrator.OrchestratorClientMixin, MgrModule):
         """
         return self.vc.create_subvolume_group(
             None, vol_name=cmd['vol_name'], group_name=cmd['group_name'],
-            pool_layout=cmd.get('pool_layout', None), mode=cmd.get('mode', '755'))
+            pool_layout=cmd.get('pool_layout', None), uid=cmd.get('uid', None),
+            gid=cmd.get('gid', None), mode=cmd.get('mode', '755'))
 
     def _cmd_fs_subvolumegroup_rm(self, inbuf, cmd):
         """
@@ -258,6 +263,8 @@ class Module(orchestrator.OrchestratorClientMixin, MgrModule):
                                         group_name=cmd.get('group_name', None),
                                         size=cmd.get('size', None),
                                         pool_layout=cmd.get('pool_layout', None),
+                                        uid=cmd.get('uid', None),
+                                        gid=cmd.get('gid', None),
                                         mode=cmd.get('mode', '755'))
 
     def _cmd_fs_subvolume_rm(self, inbuf, cmd):