"""
return os.path.join(self.subvolume_path, snapdir, snapname)
+ def make_subvol_snapdir_path(self, snapdir):
+ """
+ return the subvolume snapdir path
+ """
+ return os.path.join(self.subvolume_path, snapdir.encode('utf-8'))
+
def make_group_snap_path(self, snapdir, snapname):
"""
return the group snapshot path for a given snapshot name
"""
return os.path.join(self.group_path, snapdir, snapname)
+ def make_group_snapdir_path(self, snapdir):
+ """
+ return the group's snapdir path
+ """
+ return os.path.join(self.group_path, snapdir.encode('utf-8'))
+
def __str__(self):
return "{0}/{1}".format(self.groupid, self.subvolumeid)
raise VolumeException(-e.args[0], e.args[1])
return path
+ def get_dir_entries(self, path):
+ """
+ Get the directory names in a given path
+ :param path: the given path
+ :return: the list of directory names
+ """
+ dirs = []
+ try:
+ with self.fs.opendir(path) as dir_handle:
+ d = self.fs.readdir(dir_handle)
+ while d:
+ if (d.d_name not in (b".", b"..")) and d.is_dir():
+ dirs.append(d.d_name)
+ d = self.fs.readdir(dir_handle)
+ except cephfs.ObjectNotFound:
+ # When the given path is not found, we just return an empty list
+ return []
+ except cephfs.Error as e:
+ raise VolumeException(-e.args[0], e.args[1])
+ return dirs
+
### group operations
def create_group(self, spec, mode=0o755, pool=None):
return result
return conn_wrapper
+ def nametojson(self, names):
+ """
+ convert the list of names to json
+ """
+
+ namedict = []
+ for i in range(len(names)):
+ namedict.append({'name': names[i].decode('utf-8')})
+ return json.dumps(namedict, indent=2)
+
### subvolume operations
@connection_pool_wrap
ret = self.volume_exception_to_retval(ve)
return ret
+ @connection_pool_wrap
+ def list_subvolumes(self, fs_handle, **kwargs):
+ ret = 0, "", ""
+ groupname = kwargs['group_name']
+
+ try:
+ with SubVolume(self.mgr, fs_handle) as sv:
+ spec = SubvolumeSpec(None, groupname)
+ if not self.group_exists(sv, spec):
+ raise VolumeException(
+ -errno.ENOENT, "Subvolume group '{0}' not found".format(groupname))
+ path = sv.get_group_path(spec)
+ # When default subvolume group is not yet created we just return an empty list.
+ if path is None:
+ ret = 0, '[]', ""
+ else:
+ subvolumes = sv.get_dir_entries(path)
+ ret = 0, self.nametojson(subvolumes), ""
+ except VolumeException as ve:
+ ret = self.volume_exception_to_retval(ve)
+ return ret
+
### subvolume snapshot
@connection_pool_wrap
ret = self.volume_exception_to_retval(ve)
return ret
+ @connection_pool_wrap
+ def list_subvolume_snapshots(self, fs_handle, **kwargs):
+ ret = 0, "", ""
+ subvolname = kwargs['sub_name']
+ groupname = kwargs['group_name']
+
+ try:
+ with SubVolume(self.mgr, fs_handle) as sv:
+ spec = SubvolumeSpec(subvolname, groupname)
+ if not self.group_exists(sv, spec):
+ raise VolumeException(
+ -errno.ENOENT, "Subvolume group '{0}' not found".format(groupname))
+
+ if sv.get_subvolume_path(spec) == None:
+ raise VolumeException(-errno.ENOENT,
+ "Subvolume '{0}' not found".format(subvolname))
+
+ path = spec.make_subvol_snapdir_path(self.mgr.rados.conf_get('client_snapdir'))
+ snapshots = sv.get_dir_entries(path)
+ ret = 0, self.nametojson(snapshots), ""
+ except VolumeException as ve:
+ ret = self.volume_exception_to_retval(ve)
+ return ret
+
+
### group operations
@connection_pool_wrap
except VolumeException as ve:
return self.volume_exception_to_retval(ve)
+ @connection_pool_wrap
+ def list_subvolume_groups(self, fs_handle, **kwargs):
+ ret = 0, "", ""
+
+ try:
+ with SubVolume(self.mgr, fs_handle) as sv:
+ subvolumegroups = sv.get_dir_entries(SubvolumeSpec.DEFAULT_SUBVOL_PREFIX)
+ ret = 0, self.nametojson(subvolumegroups), ""
+ except VolumeException as ve:
+ ret = self.volume_exception_to_retval(ve)
+ return ret
+
### group snapshot
@connection_pool_wrap
ret = self.volume_exception_to_retval(ve)
return ret
+ @connection_pool_wrap
+ def list_subvolume_group_snapshots(self, fs_handle, **kwargs):
+ ret = 0, "", ""
+ groupname = kwargs['group_name']
+
+ try:
+ with SubVolume(self.mgr, fs_handle) as sv:
+ spec = SubvolumeSpec(None, groupname)
+ if not self.group_exists(sv, spec):
+ raise VolumeException(
+ -errno.ENOENT, "Subvolume group '{0}' not found".format(groupname))
+
+ path = spec.make_group_snapdir_path(self.mgr.rados.conf_get('client_snapdir'))
+ snapshots = sv.get_dir_entries(path)
+ ret = 0, self.nametojson(snapshots), ""
+ except VolumeException as ve:
+ ret = self.volume_exception_to_retval(ve)
+ return ret
+
@connection_pool_wrap
def get_subvolume_trash_entry(self, fs_handle, **kwargs):
ret = None
'desc': "Delete a CephFS volume",
'perm': 'rw'
},
+ {
+ 'cmd': 'fs subvolumegroup ls '
+ 'name=vol_name,type=CephString ',
+ 'desc': "List subvolumegroups",
+ 'perm': 'r'
+ },
{
'cmd': 'fs subvolumegroup create '
'name=vol_name,type=CephString '
'desc': "Delete a CephFS subvolume group in a volume",
'perm': 'rw'
},
+ {
+ 'cmd': 'fs subvolume ls '
+ 'name=vol_name,type=CephString '
+ 'name=group_name,type=CephString,req=false ',
+ 'desc': "List subvolumes",
+ 'perm': 'r'
+ },
{
'cmd': 'fs subvolume create '
'name=vol_name,type=CephString '
"and optionally, in a specific subvolume group",
'perm': 'rw'
},
+ {
+ 'cmd': 'fs subvolumegroup snapshot ls '
+ 'name=vol_name,type=CephString '
+ 'name=group_name,type=CephString ',
+ 'desc': "List subvolumegroup snapshots",
+ 'perm': 'r'
+ },
{
'cmd': 'fs subvolumegroup snapshot create '
'name=vol_name,type=CephString '
'desc': "Delete a snapshot of a CephFS subvolume group in a volume",
'perm': 'rw'
},
+ {
+ 'cmd': 'fs subvolume snapshot ls '
+ 'name=vol_name,type=CephString '
+ 'name=sub_name,type=CephString '
+ 'name=group_name,type=CephString,req=false ',
+ 'desc': "List subvolume snapshots",
+ 'perm': 'r'
+ },
{
'cmd': 'fs subvolume snapshot create '
'name=vol_name,type=CephString '
group_name=cmd['group_name'],
force=cmd.get('force', False))
+ def _cmd_fs_subvolumegroup_ls(self, inbuf, cmd):
+ vol_name = cmd['vol_name']
+ return self.vc.list_subvolume_groups(None, vol_name=cmd['vol_name'])
+
def _cmd_fs_subvolume_create(self, inbuf, cmd):
"""
:return: a 3-tuple of return code(int), empty string(str), error message (str)
group_name=cmd.get('group_name', None),
force=cmd.get('force', False))
+ def _cmd_fs_subvolume_ls(self, inbuf, cmd):
+ return self.vc.list_subvolumes(None, vol_name=cmd['vol_name'],
+ group_name=cmd.get('group_name', None))
+
def _cmd_fs_subvolumegroup_getpath(self, inbuf, cmd):
return self.vc.getpath_subvolume_group(
None, vol_name=cmd['vol_name'], group_name=cmd['group_name'])
snap_name=cmd['snap_name'],
force=cmd.get('force', False))
+ def _cmd_fs_subvolumegroup_snapshot_ls(self, inbuf, cmd):
+ return self.vc.list_subvolume_group_snapshots(None, vol_name=cmd['vol_name'],
+ group_name=cmd['group_name'])
+
def _cmd_fs_subvolume_snapshot_create(self, inbuf, cmd):
return self.vc.create_subvolume_snapshot(None, vol_name=cmd['vol_name'],
sub_name=cmd['sub_name'],
snap_name=cmd['snap_name'],
group_name=cmd.get('group_name', None),
force=cmd.get('force', False))
+
+ def _cmd_fs_subvolume_snapshot_ls(self, inbuf, cmd):
+ return self.vc.list_subvolume_snapshots(None, vol_name=cmd['vol_name'],
+ sub_name=cmd['sub_name'],
+ group_name=cmd.get('group_name', None))