import errno
import logging
-import sys
+import os
from typing import List, Tuple
from ..exception import VolumeException
from ..fs_util import create_pool, remove_pool, rename_pool, create_filesystem, \
remove_filesystem, rename_filesystem, create_mds, volume_exists
+from .trash import Trash
from mgr_util import open_filesystem, CephfsConnectionException
log = logging.getLogger(__name__)
-
def gen_pool_names(volname):
"""
return metadata and data pool name (from a filesystem/volume name) as a tuple
data_pools = [pools[id] for id in data_pool_ids]
return metadata_pool, data_pools
+def get_pool_ids(mgr, volname):
+ """
+ return metadata and data pools (list) id of volume as a tuple
+ """
+ fs_map = mgr.get("fs_map")
+ metadata_pool_id = None
+ data_pool_ids = [] # type: List[int]
+ for f in fs_map['filesystems']:
+ if volname == f['mdsmap']['fs_name']:
+ metadata_pool_id = f['mdsmap']['metadata_pool']
+ data_pool_ids = f['mdsmap']['data_pools']
+ break
+ if metadata_pool_id is None:
+ return None, None
+ return metadata_pool_id, data_pool_ids
+
def create_volume(mgr, volname, placement):
"""
create volume (pool, filesystem and mds)
return result
+def get_pending_subvol_deletions_count(path):
+ """
+ Get the number of pending subvolumes deletions.
+ """
+ trashdir = os.path.join(path, Trash.GROUP_NAME)
+ try:
+ num_pending_subvol_del = len(os.listdir(trashdir))
+ except OSError as e:
+ if e.errno == errno.ENOENT:
+ num_pending_subvol_del = 0
+
+ return {'pending_subvolume_deletions': num_pending_subvol_del}
+
+
@contextmanager
def open_volume(vc, volname):
"""
from .fs_util import listdir, has_subdir
-from .operations.volume import create_volume, \
- delete_volume, rename_volume, list_volumes, open_volume, get_pool_names
from .operations.group import open_group, create_group, remove_group, \
open_group_unique, set_group_attrs
+from .operations.volume import create_volume, delete_volume, rename_volume, \
+ list_volumes, open_volume, get_pool_names, get_pool_ids, get_pending_subvol_deletions_count
from .operations.subvolume import open_subvol, create_subvol, remove_subvol, \
create_clone
from .operations.trash import Trash
return rename_volume(self.mgr, volname, newvolname)
+ def volume_info(self, **kwargs):
+ ret = None
+ volname = kwargs['vol_name']
+
+ try:
+ with open_volume(self, volname) as fs_handle:
+ path = self.volspec.base_dir
+ vol_info_dict = {}
+ try:
+ st = fs_handle.statx(path.encode('utf-8'), cephfs.CEPH_STATX_SIZE,
+ cephfs.AT_SYMLINK_NOFOLLOW)
+
+ usedbytes = st['size']
+ vol_info_dict = get_pending_subvol_deletions_count(path)
+ vol_info_dict['used_size'] = int(usedbytes)
+ except cephfs.Error as e:
+ if e.args[0] == errno.ENOENT:
+ pass
+ df = self.mgr.get("df")
+ pool_stats = dict([(p['id'], p['stats']) for p in df['pools']])
+ osdmap = self.mgr.get("osd_map")
+ pools = dict([(p['pool'], p) for p in osdmap['pools']])
+ metadata_pool_id, data_pool_ids = get_pool_ids(self.mgr, volname)
+ vol_info_dict["pools"] = {"metadata": [], "data": []}
+ for pool_id in [metadata_pool_id] + data_pool_ids:
+ if pool_id == metadata_pool_id:
+ pool_type = "metadata"
+ else:
+ pool_type = "data"
+ vol_info_dict["pools"][pool_type].append({
+ 'name': pools[pool_id]['pool_name'],
+ 'used': pool_stats[pool_id]['bytes_used'],
+ 'avail': pool_stats[pool_id]['max_avail']})
+
+ mon_addr_lst = []
+ mon_map_mons = self.mgr.get('mon_map')['mons']
+ for mon in mon_map_mons:
+ ip_port = mon['addr'].split("/")[0]
+ mon_addr_lst.append(ip_port)
+ vol_info_dict["mon_addrs"] = mon_addr_lst
+ ret = 0, json.dumps(vol_info_dict, indent=4, sort_keys=True), ""
+ except VolumeException as ve:
+ ret = self.volume_exception_to_retval(ve)
+ return ret
+
### subvolume operations
def _create_subvolume(self, fs_handle, volname, group, subvolname, **kwargs):
'desc': "Rename a CephFS volume by passing --yes-i-really-mean-it flag",
'perm': 'rw'
},
+ {
+ 'cmd': 'fs volume info '
+ 'name=vol_name,type=CephString ',
+ 'desc': "Get the information of a CephFS volume",
+ 'perm': 'r'
+ },
{
'cmd': 'fs subvolumegroup ls '
'name=vol_name,type=CephString ',
cmd['new_vol_name'],
cmd.get('yes_i_really_mean_it', False))
+ @mgr_cmd_wrap
+ def _cmd_fs_volume_info(self, inbuf, cmd):
+ return self.vc.volume_info(vol_name=cmd['vol_name'])
+
@mgr_cmd_wrap
def _cmd_fs_subvolumegroup_create(self, inbuf, cmd):
"""