... of fs subvolumes and subvolume groups during their creation.
Fixes: https://tracker.ceph.com/issues/40299
Signed-off-by: Ramana Raja <rraja@redhat.com>
+import os
import json
import errno
import random
self._fs_cmd("subvolume", "rm", self.volname, subvol1, group)
self._fs_cmd("subvolumegroup", "rm", self.volname, group)
+ def test_subvolume_group_create_with_desired_mode(self):
+ group1 = self._generate_random_group_name()
+ group2 = self._generate_random_group_name()
+ # default mode
+ expected_mode1 = "755"
+ # desired mode
+ expected_mode2 = "777"
+
+ # create group
+ self._fs_cmd("subvolumegroup", "create", self.volname, group1)
+ self._fs_cmd("subvolumegroup", "create", self.volname, group2, "--mode", "777")
+
+ group1_path = os.path.join('volumes', group1)
+ group2_path = os.path.join('volumes', group2)
+
+ # check group's mode
+ actual_mode1 = self.mount_a.run_shell(['stat', '-c' '%a', group1_path]).stdout.getvalue().strip()
+ actual_mode2 = self.mount_a.run_shell(['stat', '-c' '%a', group2_path]).stdout.getvalue().strip()
+ self.assertEqual(actual_mode1, expected_mode1)
+ self.assertEqual(actual_mode2, expected_mode2)
+
+ self._fs_cmd("subvolumegroup", "rm", self.volname, group1)
+ self._fs_cmd("subvolumegroup", "rm", self.volname, group2)
+
+ def test_subvolume_create_with_desired_mode_in_group(self):
+ subvol1 = self._generate_random_subvolume_name()
+ subvol2 = self._generate_random_subvolume_name()
+ subvol3 = self._generate_random_subvolume_name()
+ group = self._generate_random_group_name()
+ # default mode
+ expected_mode1 = "755"
+ # desired mode
+ expected_mode2 = "777"
+
+ # create group
+ self._fs_cmd("subvolumegroup", "create", self.volname, group)
+
+ # create subvolume in group
+ self._fs_cmd("subvolume", "create", self.volname, subvol1, "--group_name", group)
+ self._fs_cmd("subvolume", "create", self.volname, subvol2, "--group_name", group, "--mode", "777")
+ # check whether mode 0777 also works
+ self._fs_cmd("subvolume", "create", self.volname, subvol3, "--group_name", group, "--mode", "0777")
+
+ subvol1_path = self._get_subvolume_path(self.volname, subvol1, group_name=group)
+ subvol2_path = self._get_subvolume_path(self.volname, subvol2, group_name=group)
+ subvol3_path = self._get_subvolume_path(self.volname, subvol3, group_name=group)
+
+ # check subvolume's mode
+ actual_mode1 = self.mount_a.run_shell(['stat', '-c' '%a', subvol1_path]).stdout.getvalue().strip()
+ actual_mode2 = self.mount_a.run_shell(['stat', '-c' '%a', subvol2_path]).stdout.getvalue().strip()
+ actual_mode3 = self.mount_a.run_shell(['stat', '-c' '%a', subvol3_path]).stdout.getvalue().strip()
+ self.assertEqual(actual_mode1, expected_mode1)
+ self.assertEqual(actual_mode2, expected_mode2)
+ self.assertEqual(actual_mode3, expected_mode2)
+
+ self._fs_cmd("subvolume", "rm", self.volname, subvol2, group)
+ self._fs_cmd("subvolume", "rm", self.volname, subvol1, group)
+ self._fs_cmd("subvolumegroup", "rm", self.volname, group)
+
def test_nonexistent_subvolme_group_rm(self):
group = "non_existent_group"
# at the time of subvolume, snapshot and other create operations).
return spec.is_default_group() or sv.get_group_path(spec)
+ @staticmethod
+ def octal_str_to_decimal_int(mode):
+ try:
+ return int(mode, 8)
+ except ValueError:
+ raise VolumeException(-errno.EINVAL, "Invalid mode '{0}'".format(mode))
+
### subvolume operations
- def create_subvolume(self, volname, subvolname, groupname, size, pool=None):
+ def create_subvolume(self, volname, subvolname, groupname, size, mode='755', pool=None):
ret = 0, "", ""
try:
if not self.volume_exists(volname):
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)
+ sv.create_subvolume(spec, size, pool=pool, mode=self.octal_str_to_decimal_int(mode))
except VolumeException as ve:
ret = self.volume_exception_to_retval(ve)
return ret
### group operations
- def create_subvolume_group(self, volname, groupname, pool=None):
+ def create_subvolume_group(self, volname, groupname, mode='755', pool=None):
ret = 0, "", ""
try:
if not self.volume_exists(volname):
# TODO: validate that subvol size fits in volume size
with SubVolume(self.mgr, fs_name=volname) as sv:
spec = SubvolumeSpec("", groupname)
- sv.create_group(spec, pool=pool)
+ sv.create_group(spec, pool=pool, mode=self.octal_str_to_decimal_int(mode))
except VolumeException as ve:
ret = self.volume_exception_to_retval(ve)
return ret
'cmd': 'fs subvolumegroup create '
'name=vol_name,type=CephString '
'name=group_name,type=CephString '
- 'name=pool_layout,type=CephString,req=false ',
+ 'name=pool_layout,type=CephString,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",
+ "with a specific data pool layout, and a specific numeric mode",
'perm': 'rw'
},
{
'name=sub_name,type=CephString '
'name=size,type=CephInt,req=false '
'name=group_name,type=CephString,req=false '
- 'name=pool_layout,type=CephString,req=false ',
+ 'name=pool_layout,type=CephString,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 "
- "and in a specific subvolume group",
+ "with a specific size (in bytes), a specific data pool layout, "
+ "a specific mode, and in a specific subvolume group",
'perm': 'rw'
},
{
vol_name = cmd['vol_name']
group_name = cmd['group_name']
pool_layout = cmd.get('pool_layout', None)
+ mode = cmd.get('mode', '755')
- return self.vc.create_subvolume_group(vol_name, group_name, pool=pool_layout)
+ return self.vc.create_subvolume_group(vol_name, group_name, mode=mode, pool=pool_layout)
def _cmd_fs_subvolumegroup_rm(self, inbuf, cmd):
"""
size = cmd.get('size', None)
group_name = cmd.get('group_name', None)
pool_layout = cmd.get('pool_layout', None)
+ mode = cmd.get('mode', '755')
- return self.vc.create_subvolume(vol_name, sub_name, group_name, size, pool=pool_layout)
+ return self.vc.create_subvolume(vol_name, sub_name, group_name, size, mode=mode, pool=pool_layout)
def _cmd_fs_subvolume_rm(self, inbuf, cmd):
"""