diff options
Diffstat (limited to 'glustolibs-gluster/glustolibs/gluster/glusterfile.py')
-rwxr-xr-x | glustolibs-gluster/glustolibs/gluster/glusterfile.py | 203 |
1 files changed, 184 insertions, 19 deletions
diff --git a/glustolibs-gluster/glustolibs/gluster/glusterfile.py b/glustolibs-gluster/glustolibs/gluster/glusterfile.py index 4d712a5f3..ee9b6040d 100755 --- a/glustolibs-gluster/glustolibs/gluster/glusterfile.py +++ b/glustolibs-gluster/glustolibs/gluster/glusterfile.py @@ -97,40 +97,50 @@ def get_mountpoint(host, fqpath): return None -def get_fattr(host, fqpath, fattr): +def get_fattr(host, fqpath, fattr, encode="hex"): """getfattr for filepath on remote system Args: host (str): The hostname/ip of the remote system. fqpath (str): The fully-qualified path to the file. fattr (str): name of the fattr to retrieve - + Kwargs: + encode(str): The supported types of encoding are + [hex|text|base64] + Defaults to hex type of encoding Returns: getfattr result on success. None on fail. """ - command = ("getfattr --absolute-names --only-values -n '%s' %s" % - (fattr, fqpath)) + command = ("getfattr --absolute-names -e '%s' " + "-n '%s' %s" % + (encode, fattr, fqpath)) rcode, rout, rerr = g.run(host, command) - - if rcode == 0: - return rout.strip() + if not rcode: + return rout.strip().split('=')[1].replace('"', '') g.log.error('getfattr failed: %s' % rerr) return None -def get_fattr_list(host, fqpath): +def get_fattr_list(host, fqpath, encode_hex=False): """List of xattr for filepath on remote system. Args: host (str): The hostname/ip of the remote system. fqpath (str): The fully-qualified path to the file. + Kwargs: + encode_hex(bool): Fetch xattr in hex if True + (Default:False) + Returns: Dictionary of xattrs on success. None on fail. """ - command = "getfattr --absolute-names -d -m - %s" % fqpath - rcode, rout, rerr = g.run(host, command) + cmd = "getfattr --absolute-names -d -m - {}".format(fqpath) + if encode_hex: + cmd = ("getfattr --absolute-names -d -m - -e hex {}" + .format(fqpath)) + rcode, rout, rerr = g.run(host, cmd) if rcode == 0: xattr_list = {} @@ -237,7 +247,7 @@ def get_file_stat(host, fqpath): Returns: A dictionary of file stat data. None on fail. """ - statformat = '%F:%n:%i:%a:%s:%h:%u:%g:%U:%G' + statformat = '%F$%n$%i$%a$%s$%h$%u$%g$%U$%G$%x$%y$%z$%X$%Y$%Z' command = "stat -c '%s' %s" % (statformat, fqpath) rcode, rout, rerr = g.run(host, command) if rcode == 0: @@ -245,7 +255,9 @@ def get_file_stat(host, fqpath): stat_string = rout.strip() (filetype, filename, inode, access, size, links, - uid, gid, username, groupname) = stat_string.split(":") + uid, gid, username, groupname, + atime, mtime, ctime, epoch_atime, + epoch_mtime, epoch_ctime) = stat_string.split("$") stat_data['filetype'] = filetype stat_data['filename'] = filename @@ -257,6 +269,12 @@ def get_file_stat(host, fqpath): stat_data["groupname"] = groupname stat_data["uid"] = uid stat_data["gid"] = gid + stat_data["atime"] = atime + stat_data["mtime"] = mtime + stat_data["ctime"] = ctime + stat_data["epoch_atime"] = epoch_atime + stat_data["epoch_mtime"] = epoch_mtime + stat_data["epoch_ctime"] = epoch_ctime return stat_data @@ -382,7 +400,8 @@ def get_pathinfo(host, fqpath): A dictionary of pathinfo data for a remote file. None on fail. """ pathinfo = {} - pathinfo['raw'] = get_fattr(host, fqpath, 'trusted.glusterfs.pathinfo') + pathinfo['raw'] = get_fattr(host, fqpath, 'trusted.glusterfs.pathinfo', + encode="text") pathinfo['brickdir_paths'] = re.findall(r".*?POSIX.*?:(\S+)\>", pathinfo['raw']) @@ -405,17 +424,14 @@ def is_linkto_file(host, fqpath): """ command = 'file %s' % fqpath rcode, rout, _ = g.run(host, command) - if rcode == 0: - if 'sticky empty' in rout.strip(): + # An additional ',' is there for newer platforms + if 'sticky empty' or 'sticky, empty' in rout.strip(): stat = get_file_stat(host, fqpath) if int(stat['size']) == 0: - # xattr = get_fattr(host, fqpath, - # 'trusted.glusterfs.dht.linkto') xattr = get_dht_linkto_xattr(host, fqpath) if xattr is not None: return True - return False @@ -429,7 +445,8 @@ def get_dht_linkto_xattr(host, fqpath): Returns: Return value of get_fattr trusted.glusterfs.dht.linkto call. """ - linkto_xattr = get_fattr(host, fqpath, 'trusted.glusterfs.dht.linkto') + linkto_xattr = get_fattr(host, fqpath, 'trusted.glusterfs.dht.linkto', + encode="text") return linkto_xattr @@ -480,6 +497,154 @@ def check_if_pattern_in_file(host, pattern, fqpath): return 0 +def occurences_of_pattern_in_file(node, search_pattern, filename): + """ + Get the number of occurences of pattern in the file + + Args: + node (str): Host on which the command is executed. + search_pattern (str): Pattern to be found in the file. + filename (str): File in which the pattern is to be validated + + Returns: + (int): (-1), When the file doesn't exists. + (0), When pattern doesn't exists in the file. + (number), When pattern is found and the number of + occurences of pattern in the file. + + Example: + occurences_of_pattern_in_file(node, search_pattern, filename) + """ + + ret = file_exists(node, filename) + if not ret: + g.log.error("File %s is not present on the node " % filename) + return -1 + + cmd = ("grep -c '%s' %s" % (search_pattern, filename)) + ret, out, _ = g.run(node, cmd) + if ret: + g.log.error("No occurence of the pattern found in the file %s" % + filename) + return 0 + return int(out.strip('\n')) + + +def create_link_file(node, file, link, soft=False): + """ + Create hard or soft link for an exisiting file + + Args: + node(str): Host on which the command is executed. + file(str): Path to the source file. + link(str): Path to the link file. + + Kawrgs: + soft(bool): Create soft link if True else create + hard link. + + Returns: + (bool): True if command successful else False. + + Example: + >>> create_link_file('10.20.30.40', '/mnt/mp/file.txt', + '/mnt/mp/link') + True + """ + cmd = "ln {} {}".format(file, link) + if soft: + cmd = "ln -s {} {}".format(file, link) + + ret, _, err = g.run(node, cmd) + if ret: + if soft: + g.log.error('Failed to create soft link on {} ' + 'for file {} with error {}' + .format(node, file, err)) + else: + g.log.error('Failed to create hard link on {} ' + 'for file {} with error {}' + .format(node, file, err)) + return False + return True + + +def set_acl(client, rule, fqpath): + """Set acl rule on a specific file + + Args: + client(str): Host on which the command is executed. + rule(str): The acl rule to be set on the file. + fqpath (str): The fully-qualified path to the file. + + Returns: + (bool): True if command successful else False. + """ + cmd = "setfacl -m {} {}".format(rule, fqpath) + ret, _, _ = g.run(client, cmd) + if ret: + g.log.error('Failed to set rule {} on file {}'.format(rule, fqpath)) + return False + return True + + +def get_acl(client, path, filename): + """Get all acl rules set to a file + + Args: + client(str): Host on which the command is executed. + path (str): The fully-qualified path to the dir where file is present. + filename(str): Name of the file for which rules have to be fetched. + + Returns: + (dict): A dictionary with the formatted output of the command. + (None): In case of failures + + Example: + >>> get_acl('dhcp35-4.lab.eng.blr.redhat.com', '/root/', 'file') + {'owner': 'root', 'rules': ['user::rw-', 'user:root:rwx', 'group::r--', + 'mask::rwx', 'other::r--'], 'group': 'root', 'file': 'file'} + """ + cmd = "cd {};getfacl {}".format(path, filename) + ret, out, _ = g.run(client, cmd) + if ret: + return None + + # Generate a dict out of the output + output_dict = {} + data = out.strip().split('\n') + for key, index in (('file', 0), ('owner', 1), ('group', 2)): + output_dict[key] = data[index].split(' ')[2] + output_dict['rules'] = data[3:] + + return output_dict + + +def delete_acl(client, fqpath, rule=None): + """Delete a specific or all acl rules set on a file + + Args: + client(str): Host on which the command is executed. + fqpath (str): The fully-qualified path to the file. + + Kwargs: + rule(str): The acl rule to be removed from the file. + + Returns: + (bool): True if command successful else False. + """ + # Remove all acls set on a file + cmd = "setfacl -b {}".format(fqpath) + # Remove a specific acl of the file + if rule: + cmd = "setfacl -x {} {}".format(rule, fqpath) + + ret, _, _ = g.run(client, cmd) + if ret: + return False + return True + + class GlusterFile(object): """Class to handle files specific to Gluster (client and backend)""" def __init__(self, host, fqpath): |