1
0
mirror of https://github.com/ceph/ceph synced 2025-03-30 15:31:01 +00:00

Merge PR into master

* refs/pull/28663/head:
	cephfs-shell: use consistent naming for paths
	cephfs-shell: remove unnecessary instances of to_bytes
	cephfs-shell: refactor list_items
	pybind/cephfs: improve user-friendliness of DirResult
	pybind/cephfs: avoid unicode check

Reviewed-by: Rishabh Dave <ridave@redhat.com>
This commit is contained in:
Patrick Donnelly 2019-06-20 11:09:37 -07:00
commit 50fec41094
No known key found for this signature in database
GPG Key ID: 3A2A7E25BEA8AADB
2 changed files with 207 additions and 191 deletions
src
pybind/cephfs
tools/cephfs

View File

@ -139,6 +139,7 @@ cdef extern from "cephfs/libcephfs.h" nogil:
int ceph_mkdirs(ceph_mount_info *cmount, const char *path, mode_t mode)
int ceph_closedir(ceph_mount_info *cmount, ceph_dir_result *dirp)
int ceph_opendir(ceph_mount_info *cmount, const char *name, ceph_dir_result **dirpp)
void ceph_rewinddir(ceph_mount_info *cmount, ceph_dir_result *dirp)
int ceph_chdir(ceph_mount_info *cmount, const char *path)
dirent * ceph_readdir(ceph_mount_info *cmount, ceph_dir_result *dirp)
int ceph_rmdir(ceph_mount_info *cmount, const char *path)
@ -275,8 +276,54 @@ StatResult = namedtuple('StatResult',
"st_blocks", "st_atime", "st_mtime", "st_ctime"])
cdef class DirResult(object):
cdef ceph_dir_result *handler
cdef LibCephFS lib
cdef ceph_dir_result* handle
# Bug in older Cython instances prevents this from being a static method.
# @staticmethod
# cdef create(LibCephFS lib, ceph_dir_result* handle):
# d = DirResult()
# d.lib = lib
# d.handle = handle
# return d
def __dealloc__(self):
self.close()
def __enter__(self):
if not self.handle:
raise make_ex(errno.EBADF, "dir is not open")
self.lib.require_state("mounted")
with nogil:
ceph_rewinddir(self.lib.cluster, self.handle)
return self
def __exit__(self, type_, value, traceback):
self.close()
return False
def readdir(self):
self.lib.require_state("mounted")
with nogil:
dirent = ceph_readdir(self.lib.cluster, self.handle)
if not dirent:
return None
return DirEntry(d_ino=dirent.d_ino,
d_off=dirent.d_off,
d_reclen=dirent.d_reclen,
d_type=dirent.d_type,
d_name=dirent.d_name)
def close(self):
if self.handle:
self.lib.require_state("mounted")
with nogil:
ret = ceph_closedir(self.lib.cluster, self.handle)
if ret < 0:
raise make_ex(ret, "closedir failed")
self.handle = NULL
def cstr(val, name, encoding="utf-8", opt=False):
"""
@ -293,11 +340,13 @@ def cstr(val, name, encoding="utf-8", opt=False):
return None
if isinstance(val, bytes):
return val
elif isinstance(val, unicode):
return val.encode(encoding)
else:
raise TypeError('%s must be a string' % name)
try:
v = val.encode(encoding)
except:
raise TypeError('%s must be encodeable as a bytearray' % name)
assert isinstance(v, bytes)
return v
def cstr_list(list_str, name, encoding="utf-8"):
return [cstr(s, name) for s in list_str]
@ -688,60 +737,47 @@ cdef class LibCephFS(object):
:param path: the path name of the directory to open. Must be either an absolute path
or a path relative to the current working directory.
:param dir_handler: the directory result pointer structure to fill in.
:rtype handle: the open directory stream handle
"""
self.require_state("mounted")
path = cstr(path, 'path')
cdef:
char* _path = path
ceph_dir_result *dir_handler
ceph_dir_result* handle
with nogil:
ret = ceph_opendir(self.cluster, _path, &dir_handler);
ret = ceph_opendir(self.cluster, _path, &handle);
if ret < 0:
raise make_ex(ret, "opendir failed")
d = DirResult()
d.handler = dir_handler
d.lib = self
d.handle = handle
return d
def readdir(self, DirResult dir_handler):
def readdir(self, DirResult handle):
"""
Get the next entry in an open directory.
:param dir_handler: the directory stream pointer from an opendir holding the state of the
next entry to return.
:rtype dir_handler: the next directory entry or NULL if at the end of the directory (or the directory is empty.
This pointer should not be freed by the caller, and is only safe to access between return and
the next call to readdir or closedir.
:param handle: the open directory stream handle
:rtype dentry: the next directory entry or None if at the end of the
directory (or the directory is empty. This pointer
should not be freed by the caller, and is only safe to
access between return and the next call to readdir or
closedir.
"""
self.require_state("mounted")
cdef ceph_dir_result *_dir_handler = dir_handler.handler
with nogil:
dirent = ceph_readdir(self.cluster, _dir_handler)
if not dirent:
return None
return handle.readdir()
return DirEntry(d_ino=dirent.d_ino,
d_off=dirent.d_off,
d_reclen=dirent.d_reclen,
d_type=dirent.d_type,
d_name=dirent.d_name)
def closedir(self, DirResult dir_handler):
def closedir(self, DirResult handle):
"""
Close the open directory.
:param dir_handler: the directory result pointer (set by ceph_opendir) to close
:param handle: the open directory stream handle
"""
self.require_state("mounted")
cdef:
ceph_dir_result *_dir_handler = dir_handler.handler
with nogil:
ret = ceph_closedir(self.cluster, _dir_handler)
if ret < 0:
raise make_ex(ret, "closedir failed")
return handle.close()
def mkdir(self, path, mode):
"""

View File

@ -100,40 +100,33 @@ def get_chunks(file_size):
def to_bytes(string):
return bytes(string, encoding='utf-8')
def ls(path, opts=''):
# opts tries to be like /bin/ls opts
almost_all = 'A' in opts
try:
with cephfs.opendir(path) as d:
while True:
dent = cephfs.readdir(d)
if dent is None:
return
elif almost_all and dent.d_name in (b'.', b'..'):
continue
yield dent
except cephfs.ObjectNotFound:
return []
def list_items(dir_name=''):
d = None
if not isinstance(dir_name, bytes):
dir_name = to_bytes(dir_name)
if dir_name == '':
d = cephfs.opendir(cephfs.getcwd())
else:
try:
d = cephfs.opendir(dir_name)
except libcephfs.Error:
dir_name = dir_name.decode('utf-8')
return []
dent = cephfs.readdir(d)
items = []
while dent:
items.append(dent)
dent = cephfs.readdir(d)
cephfs.closedir(d)
return items
def glob(dir_name, pattern):
if isinstance(dir_name, bytes):
dir_name = dir_name.decode('utf-8')
def glob(path, pattern):
if isinstance(path, bytes):
path = path.decode('utf-8')
paths = []
parent_dir = os.path.dirname(dir_name)
parent_dir = os.path.dirname(path)
if parent_dir == '':
parent_dir = '/'
if dir_name == '/' or is_dir_exists(os.path.basename(dir_name),
if path == '/' or is_dir_exists(os.path.basename(path),
parent_dir):
for i in list_items(dir_name)[2:]:
for i in ls(path, opts='A'):
if fnmatch.fnmatch(i.d_name, pattern):
paths.append(os.path.join(dir_name, i.d_name))
paths.append(os.path.join(path, i.d_name))
return paths
@ -177,22 +170,22 @@ def humansize(nbytes):
return '%s%s' % (f, suffixes[i])
def print_long(file_name, is_dir, human_readable):
if not isinstance(file_name, bytes):
file_name = to_bytes(file_name)
info = cephfs.stat(file_name)
file_name = os.path.basename(file_name.decode('utf-8'))
def print_long(path, is_dir, human_readable):
if not isinstance(path, bytes):
path = to_bytes(path)
info = cephfs.stat(path)
pretty = os.path.basename(path.decode('utf-8'))
if is_dir:
file_name = colorama.Style.BRIGHT + colorama.Fore.CYAN + file_name + '/' + colorama.Style.RESET_ALL
pretty = colorama.Style.BRIGHT + colorama.Fore.CYAN + pretty + '/' + colorama.Style.RESET_ALL
if human_readable:
poutput('{}\t{:10s} {} {} {} {}'.format(
mode_notation(info.st_mode),
humansize(info.st_size), info.st_uid,
info.st_gid, info.st_mtime, file_name, sep='\t'))
info.st_gid, info.st_mtime, pretty, sep='\t'))
else:
poutput('{} {:12d} {} {} {} {}'.format(
mode_notation(info.st_mode), info.st_size, info.st_uid,
info.st_gid, info.st_mtime, file_name, sep='\t'))
info.st_gid, info.st_mtime, pretty, sep='\t'))
def word_len(word):
@ -204,26 +197,26 @@ def word_len(word):
return len(word)
def is_dir_exists(dir_name, dir_=''):
if isinstance(dir_name, bytes):
dir_name = dir_name.decode('utf-8')
def is_dir_exists(path, dir_=''):
if isinstance(path, bytes):
path = path.decode('utf-8')
if isinstance(dir_, bytes):
dir_ = dir_.decode('utf-8')
path_to_stat = os.path.join(dir_, dir_name)
path_to_stat = os.path.join(dir_, path)
try:
return ((cephfs.stat(path_to_stat).st_mode & 0o0040000) != 0)
except libcephfs.Error:
return False
def is_file_exists(file_name, dir_=''):
if isinstance(file_name, bytes):
file_name = file_name.decode('utf-8')
def is_file_exists(path, dir_=''):
if isinstance(path, bytes):
path = path.decode('utf-8')
if isinstance(dir_, bytes):
dir_ = dir_.decode('utf-8')
try:
# if its not a directory, then its a file
return ((cephfs.stat(os.path.join(dir_, file_name)).st_mode & 0o0040000) == 0)
return ((cephfs.stat(os.path.join(dir_, path)).st_mode & 0o0040000) == 0)
except libcephfs.Error:
return False
@ -262,7 +255,7 @@ def copy_from_local(local_path, remote_path):
return
stdin = 1
try:
fd = cephfs.open(to_bytes(remote_path), 'w', 0o666)
fd = cephfs.open(remote_path, 'w', 0o666)
except libcephfs.Error:
poutput("error: no permission to write remote file %s" % remote_path)
return
@ -293,7 +286,7 @@ def copy_to_local(remote_path, local_path):
if len(dir_list) > 2 and dir_list[1] == '':
return
fd = open(local_path, 'wb+')
file_ = cephfs.open(to_bytes(remote_path), 'r')
file_ = cephfs.open(remote_path, 'r')
file_size = cephfs.stat(remote_path).st_size
if file_size <= 0:
return
@ -310,13 +303,13 @@ def copy_to_local(remote_path, local_path):
fd.close()
def dirwalk(dir_name):
def dirwalk(path):
"""
walk a directory tree, using a generator
"""
dir_name = os.path.normpath(dir_name)
for item in list_items(dir_name)[2:]:
fullpath = os.path.join(dir_name, item.d_name.decode('utf-8'))
path = os.path.normpath(path)
for item in ls(path, opts='A'):
fullpath = os.path.join(path, item.d_name.decode('utf-8'))
src_path = fullpath.rsplit('/', 1)[0]
yield os.path.normpath(fullpath)
@ -369,24 +362,24 @@ class CephFSShell(Cmd):
def complete_filenames(self, text, line, begidx, endidx):
if not text:
completions = [x.d_name.decode('utf-8') + '/' * int(x.is_dir())
for x in list_items(cephfs.getcwd())[2:]]
for x in ls(b".", opts='A')]
else:
if text.count('/') > 0:
completions = [text.rsplit('/', 1)[0] + '/'
+ x.d_name.decode('utf-8') + '/'
* int(x.is_dir()) for x in list_items('/'
+ text.rsplit('/', 1)[0])[2:]
* int(x.is_dir()) for x in ls('/'
+ text.rsplit('/', 1)[0], opts='A')
if x.d_name.decode('utf-8').startswith(
text.rsplit('/', 1)[1])]
else:
completions = [x.d_name.decode('utf-8') + '/'
* int(x.is_dir()) for x in list_items()[2:]
* int(x.is_dir()) for x in ls(b".", opts='A')
if x.d_name.decode('utf-8').startswith(text)]
if len(completions) == 1 and completions[0][-1] == '/':
dir_, file_ = completions[0].rsplit('/', 1)
completions.extend([dir_ + '/' + x.d_name.decode('utf-8')
+ '/' * int(x.is_dir()) for x in
list_items('/' + dir_)[2:]
ls('/' + dir_, opts='A')
if x.d_name.decode('utf-8').startswith(file_)])
return self.delimiter_complete(text, line, begidx, endidx, completions, '/')
return completions
@ -500,9 +493,7 @@ exists.')
"""
Create directory.
"""
for dir_name in args.dirs:
path = to_bytes(dir_name)
for path in args.dirs:
if args.mode:
permission = int(args.mode, 8)
else:
@ -588,13 +579,13 @@ exists.')
if args.force and dst_dir != '/' and not is_dir_exists(
dst_dir[:-1]) and not locate_file(dst_dir):
try:
cephfs.mkdirs(to_bytes(dst_dir), 0o777)
cephfs.mkdirs(dst_dir, 0o777)
except libcephfs.Error:
pass
if (not args.force) and dst_dir != '/' and not is_dir_exists(
dst_dir) and not os.path.isfile(root_src_dir):
try:
cephfs.mkdirs(to_bytes(dst_dir), 0o777)
cephfs.mkdirs(dst_dir, 0o777)
except libcephfs.Error:
pass
@ -602,7 +593,7 @@ exists.')
dir_name = os.path.join(dst_dir, dir_)
if not is_dir_exists(dir_name):
try:
cephfs.mkdirs(to_bytes(dir_name), 0o777)
cephfs.mkdirs(dir_name, 0o777)
except libcephfs.Error:
pass
@ -704,51 +695,50 @@ exists.')
ls_parser.add_argument('-a', '--all', action='store_true',
help='Do not Ignore entries starting with .')
ls_parser.add_argument('-S', action='store_true', help='Sort by file_size')
ls_parser.add_argument(
'dir_names', help='Name of Directories', nargs='*', default=[''])
ls_parser.add_argument('paths', help='Name of Directories', nargs='*', default=['.'])
@with_argparser(ls_parser)
def do_ls(self, args):
"""
List all the files and directories in the current working directory
"""
directories = args.dir_names
for dir_name in directories:
paths = args.paths
for path in paths:
values = []
items = []
if dir_name.count('*') > 0:
all_items = get_all_possible_paths(dir_name)
if path.count('*') > 0:
all_items = get_all_possible_paths(path)
if len(all_items) == 0:
continue
dir_name = all_items[0].rsplit('/', 1)[0]
if dir_name == '':
dir_name = '/'
path = all_items[0].rsplit('/', 1)[0]
if path == '':
path = '/'
dirs = []
for i in all_items:
for item in list_items(dir_name):
for item in ls(path):
d_name = item.d_name.decode('utf-8')
if os.path.basename(i) == d_name:
if item.is_dir():
dirs.append(os.path.join(dir_name, d_name))
dirs.append(os.path.join(path, d_name))
else:
items.append(item)
if dirs:
directories.extend(dirs)
paths.extend(dirs)
else:
self.poutput(dir_name, ':\n')
self.poutput(path, ':\n')
items = sorted(items, key=lambda item: item.d_name)
else:
if dir_name != '' and dir_name != cephfs.getcwd().decode(
'utf-8') and len(directories) > 1:
self.poutput(dir_name, ':\n')
items = sorted(list_items(dir_name),
if path != '' and path != cephfs.getcwd().decode(
'utf-8') and len(paths) > 1:
self.poutput(path, ':\n')
items = sorted(ls(path),
key=lambda item: item.d_name)
if not args.all:
items = [i for i in items if not i.d_name.startswith(b'.')]
if args.S:
items = sorted(items, key=lambda item: cephfs.stat(to_bytes(
dir_name + '/' + item.d_name.decode('utf-8'))).st_size)
items = sorted(items, key=lambda item: cephfs.stat(
path + '/' + item.d_name.decode('utf-8')).st_size)
if args.reverse:
items = reversed(items)
@ -761,10 +751,10 @@ exists.')
if args.long and args.H:
print_long(cephfs.getcwd().decode(
'utf-8') + dir_name + '/' + path, is_dir, True)
'utf-8') + path + '/' + path, is_dir, True)
elif args.long:
print_long(cephfs.getcwd().decode('utf-8') +
dir_name +
path +
'/' +
path,
is_dir, False)
@ -778,7 +768,7 @@ exists.')
values.append(path)
if not args.long:
print_list(values, shutil.get_terminal_size().columns)
if dir_name != directories[-1]:
if path != paths[-1]:
self.poutput('\n')
def complete_rmdir(self, text, line, begidx, endidx):
@ -788,7 +778,7 @@ exists.')
return self.complete_filenames(text, line, begidx, endidx)
rmdir_parser = argparse.ArgumentParser(description='Remove Directory.')
rmdir_parser.add_argument('dir_paths', help='Directory Path.', nargs='+')
rmdir_parser.add_argument('paths', help='Directory Path.', nargs='+')
rmdir_parser.add_argument('-p', '--parent', action='store_true',
help='Remove parent directories as necessary. \
When this option is specified, no error is reported if a directory has any \
@ -800,44 +790,44 @@ sub-directories, files')
Remove a specific Directory
"""
is_pattern = False
directories = args.dir_paths
for dir_path in directories:
if dir_path.count('*') > 0:
paths = args.paths
for path in paths:
if path.count('*') > 0:
is_pattern = True
all_items = get_all_possible_paths(dir_path)
all_items = get_all_possible_paths(path)
if len(all_items) > 0:
dir_path = all_items[0].rsplit('/', 1)[0]
if dir_path == '':
dir_path = '/'
path = all_items[0].rsplit('/', 1)[0]
if path == '':
path = '/'
dirs = []
for i in all_items:
for item in list_items(dir_path):
for item in ls(path):
d_name = item.d_name
if os.path.basename(i) == d_name:
if item.is_dir():
dirs.append(os.path.join(dir_path, d_name))
directories.extend(dirs)
dirs.append(os.path.join(path, d_name))
paths.extend(dirs)
continue
else:
is_pattern = False
path = ''
dir_path = os.path.normpath(os.path.join(
cephfs.getcwd().decode('utf-8'), dir_path))
path = os.path.normpath(os.path.join(
cephfs.getcwd().decode('utf-8'), path))
if args.parent:
files = reversed(
sorted(set(dirwalk(dir_path))))
sorted(set(dirwalk(path))))
for path in files:
path = os.path.normpath(path)
if path[1:] != dir_path:
if path[1:] != path:
try:
cephfs.rmdir(to_bytes(path))
cephfs.rmdir(path)
except libcephfs.Error:
cephfs.unlink(to_bytes(path))
if not is_pattern and dir_path != os.path.normpath(path):
cephfs.unlink(path)
if not is_pattern and path != os.path.normpath(path):
try:
cephfs.rmdir(to_bytes(dir_path))
cephfs.rmdir(path)
except libcephfs.Error:
self.poutput('error: no such directory "%s"' % dir_path)
self.poutput('error: no such directory "%s"' % path)
def complete_rm(self, text, line, begidx, endidx):
"""
@ -846,23 +836,22 @@ sub-directories, files')
return self.complete_filenames(text, line, begidx, endidx)
rm_parser = argparse.ArgumentParser(description='Remove File.')
rm_parser.add_argument('file_paths', help='File Path.', nargs='+')
rm_parser.add_argument('paths', help='File Path.', nargs='+')
@with_argparser(rm_parser)
def do_rm(self, args):
"""
Remove a specific file
"""
files = args.file_paths
for file_path in files:
if file_path.count('*') > 0:
for path in args.paths:
if path.count('*') > 0:
files.extend([i for i in get_all_possible_paths(
file_path) if is_file_exists(i)])
path) if is_file_exists(i)])
else:
try:
cephfs.unlink(to_bytes(file_path))
cephfs.unlink(path)
except libcephfs.Error:
self.poutput('%s: no such file' % file_path)
self.poutput('%s: no such file' % path)
def complete_mv(self, text, line, begidx, endidx):
"""
@ -881,7 +870,7 @@ sub-directories, files')
Rename a file or Move a file from source path to the destination
"""
try:
cephfs.rename(to_bytes(args.src_path), to_bytes(args.dest_path))
cephfs.rename(args.src_path, args.dest_path)
except libcephfs.Error:
self.poutput("error: need a file name to move to")
@ -892,29 +881,19 @@ sub-directories, files')
return self.complete_filenames(text, line, begidx, endidx)
cd_parser = argparse.ArgumentParser(description='Change working directory')
cd_parser.add_argument('dir_name', type=str,
help='Name of the directory.', default='')
cd_parser.add_argument('path', type=str, help='Name of the directory.', default='/')
@with_argparser(cd_parser)
def do_cd(self, args):
"""
Change working directory
"""
if args.dir_name == '':
cephfs.chdir(b'/')
if args.dir_name == '..':
dir_name = cephfs.getcwd().decode('utf-8').rsplit('/', 1)[0]
if dir_name != '':
cephfs.chdir(to_bytes(dir_name))
else:
cephfs.chdir(b'/')
else:
try:
cephfs.chdir(to_bytes(args.dir_name))
except libcephfs.Error:
self.poutput("%s: no such directory" % args.dir_name)
self.working_dir = cephfs.getcwd().decode('utf-8')
self.set_prompt()
try:
cephfs.chdir(args.path)
self.working_dir = cephfs.getcwd().decode('utf-8')
self.set_prompt()
except libcephfs.Error:
self.poutput("%s: no such directory" % args.path)
def do_cwd(self, arglist):
"""
@ -930,18 +909,19 @@ sub-directories, files')
chmod_parser = argparse.ArgumentParser(description='Create Directory.')
chmod_parser.add_argument('mode', type=str, action=ModeAction, help='Mode')
chmod_parser.add_argument('file_name', type=str, help='Name of the file')
chmod_parser.add_argument('paths', type=str, help='Name of the file', nargs="+")
@with_argparser(chmod_parser)
def do_chmod(self, args):
"""
Change permission of a file
"""
mode = int(args.mode, base=8)
try:
cephfs.chmod(args.file_name, mode)
except libcephfs.Error:
self.poutput('%s: no such file or directory' % args.file_name)
for path in args.paths:
mode = int(args.mode, base=8)
try:
cephfs.chmod(path, mode)
except libcephfs.Error:
self.poutput('%s: no such file or directory' % path)
def complete_cat(self, text, line, begidx, endidx):
"""
@ -950,18 +930,18 @@ sub-directories, files')
return self.complete_filenames(text, line, begidx, endidx)
cat_parser = argparse.ArgumentParser(description='')
cat_parser.add_argument('file_names', help='Name of Files', nargs='+')
cat_parser.add_argument('paths', help='Name of Files', nargs='+')
@with_argparser(cat_parser)
def do_cat(self, args):
"""
Print contents of a file
"""
for file_name in args.file_names:
if is_file_exists(file_name):
copy_to_local(file_name, '-')
for path in args.paths:
if is_file_exists(path):
copy_to_local(path, '-')
else:
self.poutput('%s: no such file' % file_name)
self.poutput('%s: no such file' % path)
umask_parser = argparse.ArgumentParser(description='Set umask value.')
umask_parser.add_argument('mode', help='Mode', type=str, action=ModeAction,
@ -985,7 +965,7 @@ sub-directories, files')
return self.complete_filenames(text, line, begidx, endidx)
write_parser = argparse.ArgumentParser(description='')
write_parser.add_argument('file_name', type=str, help='Name of File')
write_parser.add_argument('path', type=str, help='Name of File')
@with_argparser(write_parser)
def do_write(self, args):
@ -993,7 +973,7 @@ sub-directories, files')
Write data into a file.
"""
copy_from_local('-', args.file_name)
copy_from_local('-', args.path)
def complete_lcd(self, text, line, begidx, endidx):
"""
@ -1058,7 +1038,7 @@ sub-directories, files')
"""
Display the amount of available disk space for file systems
"""
for index, i in enumerate(list_items(cephfs.getcwd())[2:]):
for index, i in enumerate(ls(".", opts='A')):
if index == 0:
self.poutput('{:25s}\t{:5s}\t{:15s}{:10s}{}'.format(
"1K-blocks", "Used", "Available", "Use%", "Stored on"))
@ -1111,7 +1091,7 @@ sub-directories, files')
du_parser = argparse.ArgumentParser(
description='Disk Usage of a Directory')
du_parser.add_argument(
'dirs', type=str, help='Name of the directory.', nargs='?', default='')
'dirs', type=str, help='Name of the directory.', nargs='?', default='.')
du_parser.add_argument('-r', action='store_true',
help='Recursive Disk usage of all directories.')
@ -1142,7 +1122,7 @@ sub-directories, files')
description='Quota management for a Directory')
quota_parser.add_argument('op', choices=['get', 'set'],
help='Quota operation type.')
quota_parser.add_argument('dir', type=str, help='Name of the directory.')
quota_parser.add_argument('path', type=str, help='Name of the directory.')
quota_parser.add_argument('--max_bytes', type=int, default=-1, nargs='?',
help='Max cumulative size of the data under '
'this directory.')
@ -1155,8 +1135,8 @@ sub-directories, files')
"""
Quota management.
"""
if not is_dir_exists(args.dir):
self.poutput("error: no such directory '%s'" % args.dir)
if not is_dir_exists(args.path):
self.poutput("error: no such directory '%s'" % str(args.path))
return
if args.op == 'set':
@ -1168,12 +1148,12 @@ sub-directories, files')
if args.max_bytes >= 0:
max_bytes = to_bytes(str(args.max_bytes))
try:
cephfs.setxattr(to_bytes(args.dir), 'ceph.quota.max_bytes',
cephfs.setxattr(args.path, 'ceph.quota.max_bytes',
max_bytes, len(max_bytes),
os.XATTR_CREATE)
self.poutput('max_bytes set to %d' % args.max_bytes)
except libcephfs.Error:
cephfs.setxattr(to_bytes(args.dir), 'ceph.quota.max_bytes',
cephfs.setxattr(args.path, 'ceph.quota.max_bytes',
max_bytes, len(max_bytes),
os.XATTR_REPLACE)
self.poutput('max_bytes reset to %d' % args.max_bytes)
@ -1181,12 +1161,12 @@ sub-directories, files')
if args.max_files >= 0:
max_files = to_bytes(str(args.max_files))
try:
cephfs.setxattr(to_bytes(args.dir), 'ceph.quota.max_files',
cephfs.setxattr(args.path, 'ceph.quota.max_files',
max_files, len(max_files),
os.XATTR_CREATE)
self.poutput('max_files set to %d' % args.max_files)
except libcephfs.Error:
cephfs.setxattr(to_bytes(args.dir), 'ceph.quota.max_files',
cephfs.setxattr(args.path, 'ceph.quota.max_files',
max_files, len(max_files),
os.XATTR_REPLACE)
self.poutput('max_files reset to %d' % args.max_files)
@ -1194,7 +1174,7 @@ sub-directories, files')
max_bytes = '0'
max_files = '0'
try:
max_bytes = cephfs.getxattr(to_bytes(args.dir),
max_bytes = cephfs.getxattr(args.path,
'ceph.quota.max_bytes')
self.poutput('max_bytes: %s' % max_bytes)
except libcephfs.Error:
@ -1202,7 +1182,7 @@ sub-directories, files')
pass
try:
max_files = cephfs.getxattr(to_bytes(args.dir),
max_files = cephfs.getxattr(args.path,
'ceph.quota.max_files')
self.poutput('max_files: %s' % max_files)
except libcephfs.Error:
@ -1235,7 +1215,7 @@ sub-directories, files')
stat_parser = argparse.ArgumentParser(
description='Display file or file system status')
stat_parser.add_argument('name', type=str, help='Name of the file',
stat_parser.add_argument('paths', type=str, help='file paths',
nargs='+')
@with_argparser(stat_parser)
@ -1243,22 +1223,22 @@ sub-directories, files')
"""
Display file or file system status
"""
for files in args.name:
for path in args.paths:
try:
stat = cephfs.stat(files)
stat = cephfs.stat(path)
atime = stat.st_atime.isoformat(' ')
mtime = stat.st_mtime.isoformat(' ')
ctime = stat.st_mtime.isoformat(' ')
self.poutput("File: {}\nSize: {:d}\nBlocks: {:d}\nIO Block: {:d}\n\
Device: {:d}\tInode: {:d}\tLinks: {:d}\nPermission: {:o}/{}\tUid: {:d}\tGid: {:d}\n\
Access: {}\nModify: {}\nChange: {}".format(files, stat.st_size, stat.st_blocks,
Access: {}\nModify: {}\nChange: {}".format(path, stat.st_size, stat.st_blocks,
stat.st_blksize, stat.st_dev, stat.st_ino,
stat.st_nlink, stat.st_mode,
mode_notation(stat.st_mode), stat.st_uid,
stat.st_gid, atime, mtime, ctime))
except libcephfs.Error:
self.poutput("{}: no such file or directory".format(files))
self.poutput("{}: no such file or directory".format(path))
if __name__ == '__main__':