summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArthy Loganathan <aloganat@redhat.com>2016-05-10 17:46:36 +0530
committerRaghavendra Talur <rtalur@redhat.com>2016-06-15 04:05:20 -0700
commit2808eac9b6d08d1dd9fbafb7e2aeac92f50de0dc (patch)
tree3e7dc9c9c88b9a62920a7bda369e3588befd89b6
parent4c08d36e7c6f189499f2340eb529b7f4ceff57f6 (diff)
distaf: Added library functions for gluster tiering operations
Change-Id: I08d77bdc1ca3f804e35b69abe39df2049eb7cf70 BUG: 1334721 Signed-off-by: Arthy Loganathan <aloganat@redhat.com> Reviewed-on: http://review.gluster.org/14283 Smoke: Gluster Build System <jenkins@build.gluster.org> CentOS-regression: Gluster Build System <jenkins@build.gluster.org> Reviewed-by: karthick NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org> Reviewed-by: Raghavendra Talur <rtalur@redhat.com>
-rw-r--r--tests/distaf/distaf_libs/distaflibs-gluster/distaflibs/gluster/tiering_ops.py1065
1 files changed, 1065 insertions, 0 deletions
diff --git a/tests/distaf/distaf_libs/distaflibs-gluster/distaflibs/gluster/tiering_ops.py b/tests/distaf/distaf_libs/distaflibs-gluster/distaflibs/gluster/tiering_ops.py
new file mode 100644
index 00000000000..96557f9af15
--- /dev/null
+++ b/tests/distaf/distaf_libs/distaflibs-gluster/distaflibs/gluster/tiering_ops.py
@@ -0,0 +1,1065 @@
+#!/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 gluster tiering operations.
+"""
+
+import re
+from distaf.util import tc
+import distaflibs.gluster.volume_ops
+from distaflibs.gluster.peer_ops import peer_probe_servers
+from distaflibs.gluster.gluster_init import start_glusterd
+from distaflibs.gluster.lib_utils import list_files
+
+try:
+ import xml.etree.cElementTree as etree
+except ImportError:
+ import xml.etree.ElementTree as etree
+
+
+def add_peer_nodes_to_cluster(peers, mnode=None):
+ """Adds the given peer nodes to cluster
+
+ Args:
+ peers (list) : list of peer nodes to be attached to cluster
+
+ Kwargs:
+ mnode (str): Node on which cmd has to be executed.
+ If None, defaults to servers[0].
+
+ Returns:
+ bool: True, if peer nodes are attached to cluster
+ False, otherwise
+
+ Example:
+ add_peer_nodes_to_cluster(['peer_node1','peer_node2'])
+ """
+
+ if mnode is None:
+ mnode = tc.servers[0]
+
+ if not isinstance(peers, list):
+ peers = [peers]
+
+ ret = start_glusterd(servers=peers)
+ if not ret:
+ tc.logger.error("glusterd did not start in peer nodes")
+ return False
+
+ ret = peer_probe_servers(servers=peers, mnode=mnode)
+ if not ret:
+ tc.logger.error("Unable to do peer probe on peer machines")
+ return False
+
+ return True
+
+
+def tier_attach(volname, num_bricks_to_add, peers, replica=1, force=False,
+ mnode=None):
+ """Attaches tier to the volume
+
+ Args:
+ volname (str): volume name
+ num_bricks_to_add (str): number of bricks to be added as hot tier
+ peers (list): from these servers, hot tier will be added to volume
+
+ Kwargs:
+ replica (str): replica count of the hot tier
+ force (bool): If this option is set to True, then attach tier
+ will get executed with force option. If it is set to False,
+ then attach tier will get executed without force option
+ mnode (str): Node on which cmd has to be executed.
+ If None, defaults to servers[0].
+
+ Returns:
+ tuple: Tuple containing three elements (ret, out, err).
+ The first element 'ret' is of type 'int' and is the return value
+ of command execution.
+
+ The second element 'out' is of type 'str' and is the stdout value
+ of the command execution.
+
+ The third element 'err' is of type 'str' and is the stderr value
+ of the command execution.
+
+ Example:
+ tier_attach(testvol, '2', ['peer_node1','peer_node2'])
+ """
+
+ if mnode is None:
+ mnode = tc.servers[0]
+
+ replica = int(replica)
+ repc = ''
+ if replica != 1:
+ repc = "replica %d" % replica
+
+ frce = ''
+ if force:
+ frce = 'force'
+
+ # To Do
+ # For now, assuming brick root path is /bricks in all the servers.
+ # Later on, this will be made configurable
+
+ brick_root = "/bricks"
+ volinfo = distaflibs.gluster.volume_ops.get_volume_info(volname, mnode)
+ bricks_present = volinfo[volname]['bricks']
+ _n = 0
+ _temp = 0
+ _si = len(re.findall(r"%s_tier[0-9]+" % volname, ' '.join(bricks_present)))
+ add_tier = ''
+ for i in range(_si, _si + int(num_bricks_to_add)):
+ sn = (len(re.findall(r"%s" % peers[_n], ' '.join(bricks_present))) +
+ _temp)
+ add_tier = ("%s %s:%s/brick%d/%s_tier%d" %
+ (add_tier, peers[_n], brick_root, sn, volname, i))
+ if _n < len(peers) - 1:
+ _n = _n + 1
+ else:
+ _n = 0
+ _temp = _temp + 1
+
+ cmd = ("gluster volume tier %s attach %s %s %s --mode=script"
+ % (volname, repc, add_tier, frce))
+ return tc.run(mnode, cmd)
+
+
+def tier_start(volname, force=False, mnode=None):
+ """Starts the tier volume
+
+ Args:
+ volname (str): volume name
+
+ Kwargs:
+ force (bool): If this option is set to True, then attach tier
+ will get executed with force option. If it is set to False,
+ then attach tier will get executed without force option
+ mnode (str): Node on which cmd has to be executed.
+ If None, defaults to servers[0].
+ Returns:
+ tuple: Tuple containing three elements (ret, out, err).
+ The first element 'ret' is of type 'int' and is the return value
+ of command execution.
+
+ The second element 'out' is of type 'str' and is the stdout value
+ of the command execution.
+
+ The third element 'err' is of type 'str' and is the stderr value
+ of the command execution.
+
+ Example:
+ tier_start(testvol)
+ """
+
+ if mnode is None:
+ mnode = tc.servers[0]
+
+ frce = ''
+ if force:
+ frce = 'force'
+
+ cmd = ("gluster volume tier %s start %s --mode=script"
+ % (volname, frce))
+ return tc.run(mnode, cmd)
+
+
+def tier_status(volname, mnode=None):
+ """executes tier status command
+
+ Args:
+ volname (str): volume name
+
+ Kwargs:
+ mnode (str): Node on which cmd has to be executed.
+ If None, defaults to servers[0].
+ Returns:
+ tuple: Tuple containing three elements (ret, out, err).
+ The first element 'ret' is of type 'int' and is the return value
+ of command execution.
+
+ The second element 'out' is of type 'str' and is the stdout value
+ of the command execution.
+
+ The third element 'err' is of type 'str' and is the stderr value
+ of the command execution.
+
+ Example:
+ tier_status(testvol)
+ """
+
+ if mnode is None:
+ mnode = tc.servers[0]
+
+ cmd = "gluster volume tier %s status" % volname
+ ret = tc.run(mnode, cmd)
+
+ return ret
+
+
+def get_tier_status(volname, mnode=None):
+ """Parse the output of 'gluster tier status' command.
+
+ Args:
+ volname (str): volume name
+
+ Kwargs:
+ mnode (str): Node on which command has to be executed.
+ If None, defaults to servers[0].
+
+ Returns:
+ NoneType: None if command execution fails, parse errors.
+ dict: dict on success.
+
+ Examples:
+ >>> get_tier_status(mnode = 'abc.lab.eng.xyz.com')
+ {'node': [{'promotedFiles': '0', 'demotedFiles': '0', 'nodeName':
+ 'localhost', 'statusStr': 'in progress'}, {'promotedFiles': '0',
+ 'demotedFiles': '0', 'nodeName': '10.70.47.16', 'statusStr':
+ 'in progress'}], 'task-id': '2ed28cbd-4246-493a-87b8-1fdcce313b34',
+ 'nodeCount': '4', 'op': '7'}
+ """
+
+ if mnode is None:
+ mnode = tc.servers[0]
+
+ cmd = "gluster volume tier %s status --xml" % volname
+ ret, out, _ = tc.run(mnode, cmd, verbose=False)
+ if ret != 0:
+ tc.logger.error("Failed to execute 'tier status' on node %s. "
+ "Hence failed to get tier status.", mnode)
+ return None
+
+ try:
+ root = etree.XML(out)
+ except etree.ParseError:
+ tc.logger.error("Failed to parse the gluster tier status xml output.")
+ return None
+
+ tier_status = {}
+ tier_status["node"] = []
+ for info in root.findall("volRebalance"):
+ for element in info.getchildren():
+ if element.tag == "node":
+ status_info = {}
+ for elmt in element.getchildren():
+ status_info[elmt.tag] = elmt.text
+ tier_status[element.tag].append(status_info)
+ else:
+ tier_status[element.tag] = element.text
+ return tier_status
+
+
+def tier_detach_start(volname, mnode=None):
+ """starts detaching tier on given volume
+
+ Args:
+ volname (str): volume name
+
+ Kwargs:
+ mnode (str): Node on which cmd has to be executed.
+ If None, defaults to servers[0].
+
+ Returns:
+ tuple: Tuple containing three elements (ret, out, err).
+ The first element 'ret' is of type 'int' and is the return value
+ of command execution.
+
+ The second element 'out' is of type 'str' and is the stdout value
+ of the command execution.
+
+ The third element 'err' is of type 'str' and is the stderr value
+ of the command execution.
+
+ Example:
+ tier_detach_start(testvol)
+
+ """
+ if mnode is None:
+ mnode = tc.servers[0]
+
+ cmd = "gluster volume tier %s detach start --mode=script" % volname
+ return tc.run(mnode, cmd)
+
+
+def tier_detach_status(volname, mnode=None):
+ """executes detach tier status on given volume
+
+ Args:
+ volname (str): volume name
+
+ Kwargs:
+ mnode (str): Node on which cmd has to be executed.
+ If None, defaults to servers[0].
+
+ Returns:
+ tuple: Tuple containing three elements (ret, out, err).
+ The first element 'ret' is of type 'int' and is the return value
+ of command execution.
+
+ The second element 'out' is of type 'str' and is the stdout value
+ of the command execution.
+
+ The third element 'err' is of type 'str' and is the stderr value
+ of the command execution.
+
+ Example:
+ tier_detach_status(testvol)
+
+ """
+ if mnode is None:
+ mnode = tc.servers[0]
+
+ cmd = "gluster volume tier %s detach status --mode=script" % volname
+ return tc.run(mnode, cmd)
+
+
+def tier_detach_stop(volname, mnode=None):
+ """stops detaching tier on given volume
+
+ Args:
+ volname (str): volume name
+
+ Kwargs:
+ mnode (str): Node on which cmd has to be executed.
+ If None, defaults to servers[0].
+
+ Returns:
+ tuple: Tuple containing three elements (ret, out, err).
+ The first element 'ret' is of type 'int' and is the return value
+ of command execution.
+
+ The second element 'out' is of type 'str' and is the stdout value
+ of the command execution.
+
+ The third element 'err' is of type 'str' and is the stderr value
+ of the command execution.
+
+ Example:
+ tier_detach_stop(testvol)
+
+ """
+ if mnode is None:
+ mnode = tc.servers[0]
+
+ cmd = "gluster volume tier %s detach stop --mode=script" % volname
+ return tc.run(mnode, cmd)
+
+
+def tier_detach_commit(volname, mnode=None):
+ """commits detach tier on given volume
+
+ Args:
+ volname (str): volume name
+
+ Kwargs:
+ mnode (str): Node on which cmd has to be executed.
+ If None, defaults to servers[0].
+
+ Returns:
+ tuple: Tuple containing three elements (ret, out, err).
+ The first element 'ret' is of type 'int' and is the return value
+ of command execution.
+
+ The second element 'out' is of type 'str' and is the stdout value
+ of the command execution.
+
+ The third element 'err' is of type 'str' and is the stderr value
+ of the command execution.
+
+ Example:
+ tier_detach_commit(testvol)
+
+ """
+ if mnode is None:
+ mnode = tc.servers[0]
+
+ cmd = "gluster volume tier %s detach commit --mode=script" % volname
+ return tc.run(mnode, cmd)
+
+
+def tier_detach_force(volname, mnode=None):
+ """detaches tier forcefully on given volume
+
+ Args:
+ volname (str): volume name
+
+ Kwargs:
+ mnode (str): Node on which cmd has to be executed.
+ If None, defaults to servers[0].
+
+ Returns:
+ tuple: Tuple containing three elements (ret, out, err).
+ The first element 'ret' is of type 'int' and is the return value
+ of command execution.
+
+ The second element 'out' is of type 'str' and is the stdout value
+ of the command execution.
+
+ The third element 'err' is of type 'str' and is the stderr value
+ of the command execution.
+
+ Example:
+ tier_detach_force(testvol)
+
+ """
+ if mnode is None:
+ mnode = tc.servers[0]
+
+ cmd = "gluster volume tier %s detach force --mode=script" % volname
+ return tc.run(mnode, cmd)
+
+
+def get_detach_tier_status(volname, mnode=None):
+ """Parse the output of 'gluster volume tier detach status' command.
+
+ Args:
+ volname (str): volume name
+
+ Kwargs:
+ mnode (str): Node on which command has to be executed.
+ If None, defaults to servers[0].
+
+ Returns:
+ NoneType: None if command execution fails, parse errors.
+ dict: dict on success.
+
+ Examples:
+ >>> get_detach_tier_status("testvol", mnode = 'abc.lab.eng.xyz.com')
+ {'node': [{'files': '0', 'status': '3', 'lookups': '1', 'skipped': '0',
+ 'nodeName': 'localhost', 'failures': '0', 'runtime': '0.00', 'id':
+ '11336017-9561-4e88-9ac3-a94d4b403340', 'statusStr': 'completed',
+ 'size': '0'}, {'files': '0', 'status': '3', 'lookups': '0', 'skipped':
+ '0', 'nodeName': '10.70.47.16', 'failures': '0', 'runtime': '0.00',
+ 'id': 'a2b88b10-eba2-4f97-add2-8dc37df08b27', 'statusStr': 'completed',
+ 'size': '0'}], 'nodeCount': '4', 'aggregate': {'files': '0', 'status':
+ '3', 'lookups': '1', 'skipped': '0', 'failures': '0', 'runtime': '0.0',
+ 'statusStr': 'completed', 'size': '0'}}
+ """
+
+ if mnode is None:
+ mnode = tc.servers[0]
+
+ cmd = "gluster volume tier %s detach status --xml" % volname
+ ret, out, _ = tc.run(mnode, cmd, verbose=False)
+ if ret != 0:
+ tc.logger.error("Failed to execute 'detach tier status' on node %s. "
+ "Hence failed to get detach tier status.", mnode)
+ return None
+
+ try:
+ root = etree.XML(out)
+ except etree.ParseError:
+ tc.logger.error("Failed to parse the detach tier status xml output.")
+ return None
+
+ tier_status = {}
+ tier_status["node"] = []
+ for info in root.findall("volDetachTier"):
+ for element in info.getchildren():
+ if element.tag == "node":
+ status_info = {}
+ for elmt in element.getchildren():
+ status_info[elmt.tag] = elmt.text
+ tier_status[element.tag].append(status_info)
+ elif element.tag == "aggregate":
+ status_info = {}
+ for elmt in element.getchildren():
+ status_info[elmt.tag] = elmt.text
+ tier_status[element.tag] = status_info
+ else:
+ tier_status[element.tag] = element.text
+ return tier_status
+
+
+def tier_detach_start_and_get_taskid(volname, mnode=None):
+ """Parse the output of 'gluster volume tier detach start' command.
+
+ Args:
+ volname (str): volume name
+
+ Kwargs:
+ mnode (str): Node on which command has to be executed.
+ If None, defaults to servers[0].
+
+ Returns:
+ NoneType: None if command execution fails, parse errors.
+ dict: dict on success.
+
+ Examples:
+ >>> tier_detach_start_and_get_taskid("testvol",
+ mnode = 'abc.lab.eng.xyz.com')
+ {'task-id': '8020835c-ff0d-4ea1-9f07-62dd067e92d4'}
+ """
+
+ if mnode is None:
+ mnode = tc.servers[0]
+
+ cmd = "gluster volume tier %s detach start --xml" % volname
+ ret, out, _ = tc.run(mnode, cmd, verbose=False)
+ if ret != 0:
+ tc.logger.error("Failed to execute 'detach tier start' on node %s. "
+ "Hence failed to parse the detach tier start.", mnode)
+ return None
+
+ try:
+ root = etree.XML(out)
+ except etree.ParseError:
+ tc.logger.error("Failed to parse the gluster detach tier "
+ "start xml output.")
+ return None
+
+ tier_status = {}
+ for info in root.findall("volDetachTier"):
+ for element in info.getchildren():
+ tier_status[element.tag] = element.text
+ return tier_status
+
+
+def tier_detach_stop_and_get_status(volname, mnode=None):
+ """Parse the output of 'gluster volume tier detach stop' command.
+
+ Args:
+ volname (str): volume name
+
+ Kwargs:
+ mnode (str): Node on which command has to be executed.
+ If None, defaults to servers[0].
+
+ Returns:
+ NoneType: None if command execution fails, parse errors.
+ dict: dict on success.
+
+ Examples:
+ >>> tier_detach_stop_and_get_status("testvol",
+ mnode = 'abc.lab.eng.xyz.com')
+ {'node': [{'files': '0', 'status': '3', 'lookups': '1', 'skipped': '0',
+ 'nodeName': 'localhost', 'failures': '0', 'runtime': '0.00', 'id':
+ '11336017-9561-4e88-9ac3-a94d4b403340', 'statusStr': 'completed',
+ 'size': '0'}, {'files': '0', 'status': '3', 'lookups': '0', 'skipped':
+ '0', 'nodeName': '10.70.47.16', 'failures': '0', 'runtime': '0.00',
+ 'id': 'a2b88b12-eba2-4f97-add2-8dc37df08b27', 'statusStr': 'completed',
+ 'size': '0'}], 'nodeCount': '4', 'aggregate': {'files': '0', 'status':
+ '3', 'lookups': '1', 'skipped': '0', 'failures': '0', 'runtime': '0.0',
+ 'statusStr': 'completed', 'size': '0'}}
+ """
+
+ if mnode is None:
+ mnode = tc.servers[0]
+
+ cmd = "gluster volume tier %s detach stop --xml" % volname
+ ret, out, _ = tc.run(mnode, cmd, verbose=False)
+ if ret != 0:
+ tc.logger.error("Failed to execute 'tier start' on node %s. "
+ "Hence failed to parse the tier start.", mnode)
+ return None
+
+ try:
+ root = etree.XML(out)
+ except etree.ParseError:
+ tc.logger.error("Failed to parse the gluster detach tier stop"
+ " xml output.")
+ return None
+
+ tier_status = {}
+ tier_status["node"] = []
+ for info in root.findall("volDetachTier"):
+ for element in info.getchildren():
+ if element.tag == "node":
+ status_info = {}
+ for elmt in element.getchildren():
+ status_info[elmt.tag] = elmt.text
+ tier_status[element.tag].append(status_info)
+ elif element.tag == "aggregate":
+ status_info = {}
+ for elmt in element.getchildren():
+ status_info[elmt.tag] = elmt.text
+ tier_status[element.tag] = status_info
+ else:
+ tier_status[element.tag] = element.text
+ return tier_status
+
+
+def wait_for_detach_tier_to_complete(volname, mnode=None, timeout=300):
+ """Waits for the detach tier to complete
+
+ Args:
+ volname (str): volume name
+
+ Kwargs:
+ mnode (str): Node on which command has to be executed.
+ If None, defaults to servers[0].
+ timeout (int): timeout value to wait for detach tier to complete
+
+ Returns:
+ True on success, False otherwise
+
+ Examples:
+ >>> wait_for_detach_tier_to_complete("testvol")
+ """
+
+ if mnode is None:
+ mnode = tc.servers[0]
+
+ count = 0
+ flag = 0
+ while (count < timeout):
+ status_info = get_detach_tier_status(volname, mnode=mnode)
+ if status_info is None:
+ return False
+
+ status = status_info['aggregate']['statusStr']
+ if status == 'completed':
+ flag = 1
+ break
+
+ time.sleep(10)
+ count = count + 10
+ if not flag:
+ tc.logger.error("detach tier is not completed")
+ return False
+ else:
+ tc.logger.info("detach tier is successfully completed")
+ return True
+
+
+def get_files_from_hot_tier(volname):
+ """Lists files from hot tier for the given volume
+
+ Args:
+ volname (str): volume name
+
+ Returns:
+ Emptylist: if there are no files in hot tier.
+ list: list of files in hot tier on success.
+
+ Examples:
+ >>>get_files_from_hot_tier("testvol")
+ """
+
+ files = []
+ subvols = distaflibs.gluster.volume_ops.get_subvols(volname)
+ for subvol in subvols['hot_tier_subvols']:
+ info = subvol[0].split(':')
+ file_list = list_files(info[1], server=info[0])
+ for file in file_list:
+ if ".glusterfs" not in file:
+ files.append(file)
+
+ return files
+
+
+def get_files_from_cold_tier(volname):
+ """Lists files from cold tier for the given volume
+
+ Args:
+ volname (str): volume name
+
+ Returns:
+ Emptylist: if there are no files in cold tier.
+ list: list of files in cold tier on success.
+
+ Examples:
+ >>>get_files_from_hot_tier("testvol")
+ """
+
+ files = []
+ subvols = distaflibs.gluster.volume_ops.get_subvols(volname)
+ for subvol in subvols['cold_tier_subvols']:
+ info = subvol[0].split(':')
+ file_list = list_files(info[1], server=info[0])
+ for file in file_list:
+ if ".glusterfs" not in file:
+ files.append(file)
+
+ return files
+
+
+def get_tier_promote_frequency(volname):
+ """Gets tier promote frequency value for given volume.
+
+ Args:
+ volname (str): volume name
+
+ Returns:
+ NoneType: None if command execution fails, parse errors.
+ str: promote frequency value on success.
+
+ Examples:
+ >>>get_tier_promote_frequency("testvol")
+ """
+
+ vol_options = distaflibs.gluster.volume_ops.get_volume_option(volname)
+ if vol_options is None:
+ tc.logger.error("Failed to get volume options")
+ return None
+
+ return vol_options['cluster.tier-promote-frequency']
+
+
+def get_tier_demote_frequency(volname):
+ """Gets tier demote frequency value for given volume.
+
+ Args:
+ volname (str): volume name
+
+ Returns:
+ NoneType: None if command execution fails, parse errors.
+ str: demote frequency value on success.
+
+ Examples:
+ >>>get_tier_demote_frequency("testvol")
+ """
+
+ vol_options = distaflibs.gluster.volume_ops.get_volume_option(volname)
+ if vol_options is None:
+ tc.logger.error("Failed to get volume options")
+ return None
+
+ return vol_options['cluster.tier-demote-frequency']
+
+
+def get_tier_mode(volname):
+ """Gets tier mode for given volume.
+
+ Args:
+ volname (str): volume name
+
+ Returns:
+ NoneType: None if command execution fails, parse errors.
+ str: tier mode on success.
+
+ Examples:
+ >>>get_tier_mode("testvol")
+ """
+
+ vol_options = distaflibs.gluster.volume_ops.get_volume_option(volname)
+ if vol_options is None:
+ tc.logger.error("Failed to get volume options")
+ return None
+
+ return vol_options['cluster.tier-mode']
+
+
+def get_tier_max_mb(volname):
+ """Gets tier max mb for given volume.
+
+ Args:
+ volname (str): volume name
+
+ Returns:
+ NoneType: None if command execution fails, parse errors.
+ str: tier max mb on success.
+
+ Examples:
+ >>>get_tier_max_mb("testvol")
+ """
+
+ vol_options = distaflibs.gluster.volume_ops.get_volume_option(volname)
+ if vol_options is None:
+ tc.logger.error("Failed to get volume options")
+ return None
+
+ return vol_options['cluster.tier-max-mb']
+
+
+def get_tier_max_files(volname):
+ """Gets tier max files for given volume.
+
+ Args:
+ volname (str): volume name
+
+ Returns:
+ NoneType: None if command execution fails, parse errors.
+ str: tier max files on success.
+
+ Examples:
+ >>>get_tier_max_files("testvol")
+ """
+
+ vol_options = distaflibs.gluster.volume_ops.get_volume_option(volname)
+ if vol_options is None:
+ tc.logger.error("Failed to get volume options")
+ return None
+
+ return vol_options['cluster.tier-max-files']
+
+
+def get_tier_watermark_high_limit(volname):
+ """Gets tier watermark high limit for given volume.
+
+ Args:
+ volname (str): volume name
+
+ Returns:
+ NoneType: None if command execution fails, parse errors.
+ str: tier watermark high limit on success.
+
+ Examples:
+ >>>get_tier_watermark_high_limit("testvol")
+ """
+
+ vol_options = distaflibs.gluster.volume_ops.get_volume_option(volname)
+ if vol_options is None:
+ tc.logger.error("Failed to get volume options")
+ return None
+
+ return vol_options['cluster.watermark-hi']
+
+
+def get_tier_watermark_low_limit(volname):
+ """Gets tier watermark low limit for given volume.
+
+ Args:
+ volname (str): volume name
+
+ Returns:
+ NoneType: None if command execution fails, parse errors.
+ str: tier watermark low limit on success.
+
+ Examples:
+ >>>get_tier_watermark_low_limit("testvol")
+ """
+
+ vol_options = distaflibs.gluster.volume_ops.get_volume_option(volname)
+ if vol_options is None:
+ tc.logger.error("Failed to get volume options")
+ return None
+
+ return vol_options['cluster.watermark-low']
+
+
+def set_tier_promote_frequency(volname, value):
+ """Sets tier promote frequency value for given volume.
+
+ Args:
+ volname (str): volume name
+ value (str): promote frequency value
+
+ Returns:
+ bool: True on success, False Otherwise
+
+ Examples:
+ >>>set_tier_promote_frequency("testvol", '1000')
+ """
+
+ option = {'cluster.tier-promote-frequency': value}
+
+ if not distaflibs.gluster.volume_ops.set_volume_option(volname,
+ options=option):
+ tc.logger.error("Failed to set promote frequency to %s"
+ % value)
+ return False
+
+ return True
+
+
+def set_tier_demote_frequency(volname, value):
+ """Sets tier demote frequency value for given volume.
+
+ Args:
+ volname (str): volume name
+ value (str): demote frequency value
+
+ Returns:
+ bool: True on success, False Otherwise
+
+ Examples:
+ >>>set_tier_demote_frequency("testvol", "500")
+ """
+
+ option = {'cluster.tier-demote-frequency': value}
+
+ if not distaflibs.gluster.volume_ops.set_volume_option(volname,
+ options=option):
+ tc.logger.error("Failed to set demote frequency to %s"
+ % value)
+ return False
+
+ return True
+
+
+def set_tier_mode(volname, value):
+ """Sets tier mode for given volume.
+
+ Args:
+ volname (str): volume name
+ value (str): tier mode value
+
+ Returns:
+ bool: True on success, False Otherwise
+
+ Examples:
+ >>>set_tier_mode("testvol", "cache")
+ """
+
+ option = {'cluster.tier-mode': value}
+
+ if not distaflibs.gluster.volume_ops.set_volume_option(volname,
+ options=option):
+ tc.logger.error("Failed to set tier mode to %s"
+ % value)
+ return False
+
+ return True
+
+
+def set_tier_max_mb(volname, value):
+ """Sets tier max mb for given volume.
+
+ Args:
+ volname (str): volume name
+ value (str): tier mode value
+
+ Returns:
+ bool: True on success, False Otherwise
+
+ Examples:
+ >>>set_tier_max_mb("testvol", "50")
+ """
+
+ option = {'cluster.tier-max-mb': value}
+
+ if not distaflibs.gluster.volume_ops.set_volume_option(volname,
+ options=option):
+ tc.logger.error("Failed to set tier max mb to %s"
+ % value)
+ return False
+
+ return True
+
+
+def set_tier_max_files(volname, value):
+ """Sets tier max files for given volume.
+
+ Args:
+ volname (str): volume name
+ value (str): tier mode value
+
+ Returns:
+ bool: True on success, False Otherwise
+
+ Examples:
+ >>>set_tier_max_files("testvol", "10")
+ """
+
+ option = {'cluster.tier-max-files': value}
+
+ if not distaflibs.gluster.volume_ops.set_volume_option(volname,
+ options=option):
+ tc.logger.error("Failed to set tier max files to %s"
+ % value)
+ return False
+
+ return True
+
+
+def set_tier_watermark_high_limit(volname, value):
+ """Sets tier watermark high limit for given volume.
+
+ Args:
+ volname (str): volume name
+ value (str): tier mode value
+
+ Returns:
+ bool: True on success, False Otherwise
+
+ Examples:
+ >>>set_tier_watermark_high_limit("testvol", "95")
+ """
+
+ option = {'cluster.watermark-hi': value}
+
+ if not distaflibs.gluster.volume_ops.set_volume_option(volname,
+ options=option):
+ tc.logger.error("Failed to set tier watermark high limit to %s"
+ % value)
+ return False
+
+ return True
+
+
+def set_tier_watermark_low_limit(volname, value):
+ """Sets tier watermark low limit for given volume.
+
+ Args:
+ volname (str): volume name
+ value (str): tier mode value
+
+ Returns:
+ bool: True on success, False Otherwise
+
+ Examples:
+ >>>set_tier_watermark_low_limit("testvol", "40")
+ """
+
+ option = {'cluster.watermark-low': value}
+
+ if not distaflibs.gluster.volume_ops.set_volume_option(volname,
+ options=option):
+ tc.logger.error("Failed to set tier watermark low limit to %s"
+ % value)
+ return False
+
+ return True
+
+
+def get_tier_pid(volname, mnode):
+ """Gets tier pid for given volume.
+
+ Args:
+ volname (str): volume name
+ mnode (str): Node on which command has to be executed.
+
+ Returns:
+ NoneType: None if command execution fails, parse errors.
+ str: pid of tier process on success.
+
+ Examples:
+ >>>get_tier_pid("testvol", "abc.xyz.com")
+ """
+
+ cmd = ("ps -ef | grep -v grep | grep '/var/log/glusterfs/%s-tier.log' |"
+ "awk '{print $2}'" % volname)
+ ret, out, err = tc.run(mnode, cmd)
+ if ret != 0:
+ tc.logger.error("Failed to execute 'ps' cmd")
+ return None
+
+ return out.strip("\n")
+
+
+def is_tier_process_running(volname, mnode):
+ """Checks whether tier process is running
+
+ Args:
+ volname (str): volume name
+ mnode (str): Node on which command has to be executed.
+
+ Returns:
+ True on success, False otherwise
+
+ Examples:
+ >>>is_tier_process_running("testvol", "abc.xyz.com")
+ """
+
+ pid = get_tier_pid(volname, mnode)
+ if pid == '':
+ return False
+ return True