diff options
Diffstat (limited to 'tests/distaf/distaf_libs/io_libs/file_ops.py')
-rw-r--r-- | tests/distaf/distaf_libs/io_libs/file_ops.py | 245 |
1 files changed, 245 insertions, 0 deletions
diff --git a/tests/distaf/distaf_libs/io_libs/file_ops.py b/tests/distaf/distaf_libs/io_libs/file_ops.py new file mode 100644 index 00000000000..e5c17432c44 --- /dev/null +++ b/tests/distaf/distaf_libs/io_libs/file_ops.py @@ -0,0 +1,245 @@ +#!/usr/bin/env python +# This file is part of DiSTAF +# Copyright (C) 2015-2016 Red Hat, Inc. <http://www.redhat.com> +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +""" +Description: Library for file operations. +""" + + +import re +import socket +from distaf.util import tc + + +def write_file(filename, file_contents=" ", create_mode='', filesize='', \ + server=''): + """ + This module writes the file along with file contents + @paramater: + * filename - <str> absolute path name of the file to be created + * file_contents - <str> (optional) file content + * create_mode - <str> (optional) mode to create the file + * filesize - <str> (optional) filesize + * server - <str> (optional) name of the server to write the + file. If not given, the function takes the + first node from config file + @Returns: True, on success + False, on failure + """ + if server == '': + server = tc.nodes[0] + + if create_mode == '': + create_mode = 'open' + + if create_mode != 'open': + try: + conn = tc.get_connection(server, 'root') + if conn == -1: + tc.logger.error("Unable to get connection to 'root' of " + "node %s" % server) + return False + if not conn.modules.os.path.exists(conn.modules.os.path.\ + dirname(filename)): + conn.modules.os.makedirs(conn.modules.os.path.\ + dirname(filename)) + except: + tc.logger.error("Exception occured while creating directory for " + "file %s" % filename) + return False + finally: + conn.close() + + if create_mode == 'open': + try: + conn = tc.get_connection(server, 'root') + if conn == -1: + tc.logger.error("Unable to get connection to 'root' of node " + "%s" % server) + return False + + if not conn.modules.os.path.exists(conn.modules.os.path.\ + dirname(filename)): + conn.modules.os.makedirs(conn.modules.os.path.\ + dirname(filename)) + + with conn.builtin.open(filename, 'w') as _filehandle: + _filehandle.write(file_contents) + except: + tc.logger.error("Exception occured while writing file %s" \ + % filename) + return False + + finally: + conn.close() + elif create_mode == 'echo': + cmd = "echo " + file_contents + " > " + filename + ret, _, _ = tc.run(server, cmd) + if ret != 0: + return False + elif create_mode == 'touch': + cmd = "touch " + filename + ret, _, _ = tc.run(server, cmd) + if ret != 0: + return False + elif create_mode == 'dd': + if filesize == '': + tc.logger.error("Invalid argument for dd cmd. Pass correct \ + number of parameters") + return False + + cmd = "dd if=/dev/zero of=%s bs=%s count=1" % (filename, filesize) + ret, _, _ = tc.run(server, cmd) + if ret != 0: + return False + + return True + + +def remove_file(filename, server=''): + """ + This module removes the given file + @paramater: + * filename - <str> absolute path name of the file to be created + * server - <str> (optional) name of the server to write the + file. If not given, the function takes the + first node from config file + @Returns: True, on success + False, on failure + """ + if server == '': + server = tc.nodes[0] + try: + conn = tc.get_connection(server, 'root') + if conn == -1: + tc.logger.error("Unable to get connection to 'root' of node %s" \ + % server) + return False + if conn.modules.os.path.exists(filename): + conn.modules.os.remove(filename) + except: + tc.logger.error("Exception occured while removing file %s" % filename) + return False + + finally: + conn.close() + + return True + + +def calculate_checksum(file_list, server=''): + """ + This module calculates checksum (sha256sum) for the given file list + @paramater: + * file_list - <list> absolute file names for which checksum to be + calculated + * server - <str> (optional) name of the server. + If not given, the function takes the + first node from config file + @Returns: checksum value in dict format, on success + None, on failure + """ + if server == '': + server = tc.nodes[0] + + cmd = "sha256sum %s" % ' '.join(file_list) + ret = tc.run(server, cmd) + if ret[0] != 0: + tc.logger.error("Failed to execute checksum command in server %s" \ + % server) + return None + + checksum_dict = {} + for line in ret[1].split('\n')[:-1]: + match = re.search(r'^(\S+)\s+(\S+)', line.strip()) + if match is None: + tc.logger.error("checksum output is not in \ + expected format") + return None + + checksum_dict[match.group(2)] = match.group(1) + + return checksum_dict + + +def get_extended_attributes_info(file_list, encoding='hex', attr_name='', \ + server=''): + """ + This module gets extended attribute info for the given file list + @paramater: + * file_list - <list> absolute file names + * encoding - <str> (optional) encoding format + * server - <str> (optional) name of the server. + If not given, the function takes the + first node from config file + @Returns: Extended attribute info in dict format, on success + None, on failure + """ + if server == '': + server = tc.nodes[0] + + server = socket.gethostbyname(server) + if attr_name == '': + cmd = "getfattr -d -m . -e %s %s" % (encoding, ' '.join(file_list)) + else: + cmd = "getfattr -d -m . -n %s %s" % (attr_name, ' '.join(file_list)) + + ret = tc.run(server, cmd) + if ret[0] != 0: + tc.logger.error("Failed to execute getfattr command in server %s" \ + % server) + return None + + attr_dict = {} + for each_attr in ret[1].split('\n\n')[:-1]: + for line in each_attr.split('\n'): + if line.startswith('#'): + match = re.search(r'.*file:\s(\S+).*', line) + if match is None: + tc.logger.error("getfattr output isn't in expected format") + return None + key = "/" + match.group(1) + attr_dict[key] = {} + else: + output = line.split('=') + attr_dict[key][output[0]] = output[1] + return attr_dict + + +def get_filepath_from_rhsnode(filename, server=''): + """ + This module gets filepath of the given file from rhsnode + @paramater: + * filename - <str> absolute name of the file + * server - <str> (optional) name of the server. + If not given, the function takes the + first client from config file + @Returns: file path for the given file in rhs node in list format + on success None, on failure + """ + if server == '': + server = tc.clients[0] + + output = get_extended_attributes_info([filename], \ + attr_name='trusted.glusterfs.pathinfo', server=server) + if output is None: + tc.logger.error("Failed to get path info") + return None + + pathinfo = output[filename]['trusted.glusterfs.pathinfo'] + return re.findall(".*?POSIX.*?:(\S+)\>", pathinfo) |