mirror of
https://github.com/ceph/ceph
synced 2025-03-30 15:31:01 +00:00
Merge PR #28663 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:
commit
50fec41094
src
@ -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):
|
||||
"""
|
||||
|
@ -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__':
|
||||
|
Loading…
Reference in New Issue
Block a user