summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorArthy Loganathan <aloganat@redhat.com>2016-06-26 23:14:35 +0530
committerRaghavendra Talur <rtalur@redhat.com>2016-06-26 11:19:56 -0700
commit8b53bfab1e86b7c110e5f2bab464678c4c99758a (patch)
treeee80314b73b7a0c6da1d0bcf6a0eb6a0fdff4aa1 /tests
parent931c656d6207645d2a7572cacf674f2b77f411f7 (diff)
distaf: Modified volume_ops library
Modified gluster volume ops library modules Change-Id: I2ef5ca44f3a4a9844aee48f3688e8617dbbb4fcd BUG: 1350245 Signed-off-by: Arthy Loganathan <aloganat@redhat.com> Reviewed-on: http://review.gluster.org/14801 NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org> CentOS-regression: Gluster Build System <jenkins@build.gluster.org> Reviewed-by: ShwethaHPanduranga Smoke: Gluster Build System <jenkins@build.gluster.org>
Diffstat (limited to 'tests')
-rw-r--r--tests/distaf/distaf_libs/distaflibs-gluster/distaflibs/gluster/volume_ops.py719
1 files changed, 550 insertions, 169 deletions
diff --git a/tests/distaf/distaf_libs/distaflibs-gluster/distaflibs/gluster/volume_ops.py b/tests/distaf/distaf_libs/distaflibs-gluster/distaflibs/gluster/volume_ops.py
index 64c77ea047f..58939377939 100644
--- a/tests/distaf/distaf_libs/distaflibs-gluster/distaflibs/gluster/volume_ops.py
+++ b/tests/distaf/distaf_libs/distaflibs-gluster/distaflibs/gluster/volume_ops.py
@@ -127,53 +127,115 @@ def create_volume(volname, mnode=None, dist=1, rep=1, stripe=1, trans='tcp',
return ret
-def start_volume(volname, mnode='', force=False):
- """
- Starts the gluster volume
- Returns True if success and False if failure
+def start_volume(volname, mnode=None, force=False):
+ """Starts the gluster volume
+
+ Args:
+ volname (str): volume name
+
+ Kwargs:
+ mnode (str): Node on which cmd has to be executed.
+ If None, defaults to servers[0].
+ force (bool): If this option is set to True, then start volume
+ will get executed with force option. If it is set to False,
+ then start volume will get executed without force option
+
+ 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:
+ start_volume("testvol")
"""
- if mnode == '':
+ if mnode is None:
mnode = tc.servers[0]
frce = ''
if force:
frce = 'force'
- ret = tc.run(mnode, "gluster volume start %s %s" % (volname, frce))
- if ret[0] != 0:
- return False
- return True
+ cmd = "gluster volume start %s %s --mode=script" % (volname, frce)
+ return tc.run(mnode, cmd)
-def stop_volume(volname, mnode='', force=False):
- """
- Stops the gluster volume
- Returns True if success and False if failure
+def stop_volume(volname, mnode=None, force=False):
+ """Stops the gluster volume
+
+ Args:
+ volname (str): volume name
+
+ Kwargs:
+ mnode (str): Node on which cmd has to be executed.
+ If None, defaults to servers[0].
+ force (bool): If this option is set to True, then stop volume
+ will get executed with force option. If it is set to False,
+ then stop volume will get executed without force option
+
+ 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:
+ stop_volume("testvol")
"""
- if mnode == '':
+ if mnode is None:
mnode = tc.servers[0]
frce = ''
if force:
frce = 'force'
- ret = tc.run(mnode, "gluster volume stop %s %s --mode=script" \
- % (volname, frce))
- if ret[0] != 0:
- return False
- return True
+ cmd = "gluster volume stop %s %s --mode=script" % (volname, frce)
+ return tc.run(mnode, cmd)
-def delete_volume(volname, mnode=''):
- """
- Deletes the gluster volume
- Returns True if success and False if failure
+def delete_volume(volname, mnode=None):
+ """Deletes the gluster volume if given volume exists in
+ gluster and deletes the directories in the bricks
+ associated with the 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:
+ bool: True, if volume is deleted
+ False, otherwise
"""
- if mnode == '':
+
+ if mnode is None:
mnode = tc.servers[0]
+
volinfo = get_volume_info(volname, mnode)
if volinfo is None or volname not in volinfo:
tc.logger.info("Volume %s does not exist in %s" % (volname, mnode))
return True
- bricks = volinfo[volname]['bricks']
- ret = tc.run(mnode, "gluster volume delete %s --mode=script" % volname)
- if ret[0] != 0:
+
+ if volinfo[volname]['typeStr'] == 'Tier':
+ tmp_hot_brick = volinfo[volname]["bricks"]["hotBricks"]["brick"]
+ hot_bricks = [x["name"] for x in tmp_hot_brick if "name" in x]
+ tmp_cold_brick = volinfo[volname]["bricks"]["coldBricks"]["brick"]
+ cold_bricks = [x["name"] for x in tmp_cold_brick if "name" in x]
+ bricks = hot_bricks + cold_bricks
+ else:
+ bricks = [x["name"] for x in volinfo[volname]["bricks"]["brick"]
+ if "name" in x]
+ ret, _, _ = tc.run(mnode, "gluster volume delete %s --mode=script"
+ % volname)
+ if ret != 0:
return False
try:
del tc.global_flag[volname]
@@ -186,82 +248,81 @@ def delete_volume(volname, mnode=''):
return True
-def reset_volume(volname, mnode='', force=False):
- """
- Reset the gluster volume
- Returns True if success and False if failure
+def reset_volume(volname, mnode=None, force=False):
+ """Resets the gluster volume
+
+ Args:
+ volname (str): volume name
+
+ Kwargs:
+ mnode (str): Node on which cmd has to be executed.
+ If None, defaults to servers[0].
+ force (bool): If this option is set to True, then reset volume
+ will get executed with force option. If it is set to False,
+ then reset volume will get executed without force option
+
+ 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:
+ reset_volume("testvol")
"""
- if mnode == '':
+ if mnode is None:
mnode = tc.servers[0]
frce = ''
if force:
frce = 'force'
- ret = tc.run(mnode, "gluster volume reset %s %s --mode=script" \
- % (volname, frce))
- if ret[0] != 0:
- return False
- return True
+ cmd = "gluster volume reset %s %s --mode=script" % (volname, frce)
+ return tc.run(mnode, cmd)
-def cleanup_volume(volname, mnode=''):
- """
- stops and deletes the volume
- returns True on success and False otherwise
+def cleanup_volume(volname, mnode=None):
+ """deletes snapshots in the volume, stops and deletes the gluster
+ volume if given volume exists in gluster and deletes the
+ directories in the bricks associated with the given volume
+
+ Args:
+ volname (str): volume name
- TODO: Add snapshot cleanup part here
+ Kwargs:
+ mnode (str): Node on which cmd has to be executed.
+ If None, defaults to servers[0].
+
+ Returns:
+ bool: True, if volume is deleted successfully
+ False, otherwise
+
+ Example:
+ cleanup_volume("testvol")
"""
- if mnode == '':
+ from distaflibs.gluster.snap_ops import snap_delete_by_volumename
+
+ if mnode is None:
mnode = tc.servers[0]
- ret = stop_volume(volname, mnode, True) | \
- delete_volume(volname, mnode)
- if not ret:
- tc.logger.error("Unable to cleanup the volume %s" % volname)
- return False
- return True
+ ret, _, _ = snap_delete_by_volumename(volname, mnode=mnode)
+ if ret != 0:
+ tc.logger.error("Failed to delete the snapshots in "
+ "volume %s" % volname)
+ return False
-def setup_meta_vol(servers=''):
- """
- Creates, starts and mounts the gluster meta-volume on the servers
- specified.
- """
- if servers == '':
- servers = tc.servers
- meta_volname = 'gluster_shared_storage'
- mount_point = '/var/run/gluster/shared_storage'
- metav_dist = int(tc.config_data['META_VOL_DIST_COUNT'])
- metav_rep = int(tc.config_data['META_VOL_REP_COUNT'])
- _num_bricks = metav_dist * metav_rep
- repc = ''
- if metav_rep > 1:
- repc = "replica %d" % metav_rep
- bricks = ''
- brick_root = "/bricks"
- _n = 0
- for i in range(0, _num_bricks):
- bricks = "%s %s:%s/%s_brick%d" % (bricks, servers[_n], \
- brick_root, meta_volname, i)
- if _n < len(servers) - 1:
- _n = _n + 1
- else:
- _n = 0
- gluster_cmd = "gluster volume create %s %s %s force" \
- % (meta_volname, repc, bricks)
- ret = tc.run(servers[0], gluster_cmd)
- if ret[0] != 0:
- tc.logger.error("Unable to create meta volume")
+ ret, _, _ = stop_volume(volname, mnode, True)
+ if ret != 0:
+ tc.logger.error("Failed to stop volume %s" % volname)
return False
- ret = start_volume(meta_volname, servers[0])
+
+ ret = delete_volume(volname, mnode)
if not ret:
- tc.logger.error("Unable to start the meta volume")
+ tc.logger.error("Unable to cleanup the volume %s" % volname)
return False
- time.sleep(5)
- for server in servers:
- ret = mount_volume(meta_volname, 'glusterfs', mount_point, server, \
- server)
- if ret[0] != 0:
- tc.logger.error("Unable to mount meta volume on %s" % server)
- return False
return True
@@ -344,11 +405,51 @@ def setup_vol(volname, mnode=None, dist=1, rep=1, dispd=1, red=1,
return True
+def volume_status(volname='all', service='', options='', mnode=None):
+ """Executes gluster volume status cli command
+
+ Args:
+ volname (str): volume name
+
+ Kwargs:
+ mnode (str): Node on which cmd has to be executed.
+ If None, defaults to servers[0].
+ volname (str): volume name. Defaults to 'all'
+ service (str): name of the service to get status.
+ serivce can be, [nfs|shd|<BRICK>|quotad]], If not given,
+ the function returns all the services
+ options (str): options can be,
+ [detail|clients|mem|inode|fd|callpool|tasks]. If not given,
+ the function returns the output of gluster volume status
+
+ 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:
+ volume_status()
+ """
+ if mnode is None:
+ mnode = tc.servers[0]
+
+ cmd = "gluster vol status %s %s %s" % (volname, service, options)
+
+ return tc.run(mnode, cmd)
+
+
def _parse_volume_status_xml(root_xml):
"""
Helper module for get_volume_status. It takes root xml object as input,
parses and returns the 'volume' tag xml object.
"""
+
for element in root_xml:
if element.findall("volume"):
return element.findall("volume")
@@ -359,8 +460,8 @@ def _parse_volume_status_xml(root_xml):
def parse_xml(tag_obj):
"""
- This module takes any xml element object and parses all the child nodes
- and returns the parsed data in dictionary format
+ This helper module takes any xml element object and parses all the child
+ nodes and returns the parsed data in dictionary format
"""
node_dict = {}
for tag in tag_obj:
@@ -373,36 +474,59 @@ def parse_xml(tag_obj):
return node_dict
-def get_volume_status(volname='all', service='', options='', mnode=''):
+def get_volume_status(volname='all', service='', options='', mnode=None):
"""
This module gets the status of all or specified volume(s)/brick
- @parameter:
- * mnode - <str> (optional) name of the node to execute the volume
- status command. If not given, the function takes the
- first node from config file
- * volname - <str> (optional) name of the volume to get status. It not
- given, the function returns the status of all volumes
- * service - <str> (optional) name of the service to get status.
- serivce can be, [nfs|shd|<BRICK>|quotad]], If not given,
- the function returns all the services
- * options - <str> (optional) options can be,
- [detail|clients|mem|inode|fd|callpool|tasks]. If not given,
- the function returns the output of gluster volume status
- @Returns: volume status in dict of dictionary format, on success
- None, on failure
+
+ Kwargs:
+ mnode (str): Node on which cmd has to be executed.
+ If None, defaults to servers[0].
+ volname (str): volume name. Defaults to 'all'
+ service (str): name of the service to get status.
+ serivce can be, [nfs|shd|<BRICK>|quotad]], If not given,
+ the function returns all the services
+ options (str): options can be,
+ [detail|clients|mem|inode|fd|callpool|tasks]. If not given,
+ the function returns the output of gluster volume status
+ Returns:
+ dict: volume status in dict of dictionary format, on success
+ NoneType: on failure
+
+ Example:
+ get_volume_status(volname="testvol")
+ >>>{'testvol': {'10.70.47.89': {'/bricks/brick1/a11': {'status': '1',
+ 'pid': '28963', 'bricktype': 'cold', 'port': '49163', 'peerid':
+ '7fc9015e-8134-4753-b837-54cbc6030c98', 'ports': {'rdma': 'N/A',
+ 'tcp': '49163'}}, '/bricks/brick2/a31': {'status': '1', 'pid':
+ '28982', 'bricktype': 'cold', 'port': '49164', 'peerid':
+ '7fc9015e-8134-4753-b837-54cbc6030c98', 'ports': {'rdma': 'N/A',
+ 'tcp': '49164'}}, 'NFS Server': {'status': '1', 'pid': '30525',
+ 'port': '2049', 'peerid': '7fc9015e-8134-4753-b837-54cbc6030c98',
+ 'ports': {'rdma': 'N/A', 'tcp': '2049'}}, '/bricks/brick1/a12':
+ {'status': '1', 'pid': '30505', 'bricktype': 'hot', 'port': '49165',
+ 'peerid': '7fc9015e-8134-4753-b837-54cbc6030c98', 'ports': {'rdma':
+ 'N/A', 'tcp': '49165'}}}, '10.70.47.118': {'/bricks/brick1/a21':
+ {'status': '1', 'pid': '5427', 'bricktype': 'cold', 'port': '49162',
+ 'peerid': '5397d8f5-2986-453a-b0b5-5c40a9bb87ff', 'ports': {'rdma':
+ 'N/A', 'tcp': '49162'}}, '/bricks/brick2/a41': {'status': '1', 'pid':
+ '5446', 'bricktype': 'cold', 'port': '49163', 'peerid':
+ '5397d8f5-2986-453a-b0b5-5c40a9bb87ff', 'ports': {'rdma': 'N/A',
+ 'tcp': '49163'}}, 'NFS Server': {'status': '1', 'pid': '6397', 'port':
+ '2049', 'peerid': '5397d8f5-2986-453a-b0b5-5c40a9bb87ff', 'ports':
+ {'rdma': 'N/A', 'tcp': '2049'}}}}}
"""
- if mnode == '':
+ if mnode is None:
mnode = tc.servers[0]
cmd = "gluster vol status %s %s %s --xml" % (volname, service, options)
- ret = tc.run(mnode, cmd)
- if ret[0] != 0:
+ ret, out, _ = tc.run(mnode, cmd)
+ if ret != 0:
tc.logger.error("Failed to execute gluster volume status command")
return None
- root = etree.XML(ret[1])
+ root = etree.XML(out)
volume_list = _parse_volume_status_xml(root)
if volume_list is None:
tc.logger.error("No volumes exists in the gluster")
@@ -412,6 +536,8 @@ def get_volume_status(volname='all', service='', options='', mnode=''):
for volume in volume_list:
tmp_dict1 = {}
tmp_dict2 = {}
+ hot_bricks = []
+ cold_bricks = []
vol_name = [vol.text for vol in volume if vol.tag == "volName"]
# parsing volume status xml output
@@ -428,16 +554,45 @@ def get_volume_status(volname='all', service='', options='', mnode=''):
else:
tmp_dict2[node_name] = [tmp_dict3]
else:
- nodes = volume.findall("node")
+ elem_tag = []
+ for elem in volume.getchildren():
+ elem_tag.append(elem.tag)
+ if ('hotBricks' in elem_tag) or ('coldBricks' in elem_tag):
+ for elem in volume.getchildren():
+ if (elem.tag == 'hotBricks'):
+ nodes = elem.findall("node")
+ hot_bricks = [node.find('path').text
+ for node in nodes
+ if (
+ node.find('path').text.startswith('/'))]
+ if (elem.tag == 'coldBricks'):
+ for n in elem.findall("node"):
+ nodes.append(n)
+ cold_bricks = [node.find('path').text
+ for node in nodes
+ if (
+ (node.find('path').
+ text.startswith('/')))]
+ else:
+ nodes = volume.findall("node")
+
for each_node in nodes:
if each_node.find('path').text.startswith('/'):
node_name = each_node.find('hostname').text
+ elif each_node.find('path').text == 'localhost':
+ node_name = mnode
else:
node_name = each_node.find('path').text
node_dict = parse_xml(each_node)
tmp_dict3 = {}
if "hostname" in node_dict.keys():
if node_dict['path'].startswith('/'):
+ if node_dict['path'] in hot_bricks:
+ node_dict["bricktype"] = 'hot'
+ elif node_dict['path'] in cold_bricks:
+ node_dict["bricktype"] = 'cold'
+ else:
+ node_dict["bricktype"] = 'None'
tmp = node_dict["path"]
tmp_dict3[node_dict["path"]] = node_dict
else:
@@ -445,7 +600,6 @@ def get_volume_status(volname='all', service='', options='', mnode=''):
tmp = node_dict["hostname"]
del tmp_dict3[tmp]["path"]
del tmp_dict3[tmp]["hostname"]
-
if node_name in tmp_dict1.keys():
tmp_dict1[node_name].append(tmp_dict3)
else:
@@ -458,41 +612,48 @@ def get_volume_status(volname='all', service='', options='', mnode=''):
tmp_dict2[node_name] = tmp_dict4
vol_status[vol_name[0]] = tmp_dict2
- tc.logger.debug("Volume status output: %s" \
+ tc.logger.debug("Volume status output: %s"
% pformat(vol_status, indent=10))
return vol_status
-def get_volume_option(volname, option='all', server=''):
- """
- This module gets the option values for the given volume.
- @parameter:
- * volname - <str> name of the volume to get status.
- * option - <str> (optional) name of the volume option to get status.
+def get_volume_option(volname, option='all', mnode=None):
+ """gets the option values for the given volume.
+
+ Args:
+ volname (str): volume name
+
+ Kwargs:
+ option (str): volume option to get status.
If not given, the function returns all the options for
the given volume
- * server - <str> (optional) name of the server to execute the volume
- status command. If not given, the function takes the
- first node from config file
- @Returns: value for the given volume option in dict format, on success
- None, on failure
+ mnode (str): Node on which cmd has to be executed.
+ If None, defaults to servers[0].
+
+ Returns:
+ dict: value for the given volume option in dict format, on success
+ NoneType: on failure
+
+ Example:
+ get_volume_option("testvol")
"""
- if server == '':
- server = tc.servers[0]
+ if mnode is None:
+ mnode = tc.servers[0]
cmd = "gluster volume get %s %s" % (volname, option)
- ret = tc.run(server, cmd)
- if ret[0] != 0:
- tc.logger.error("Failed to execute gluster volume get command")
+ ret, out, _ = tc.run(mnode, cmd)
+ if ret != 0:
+ tc.logger.error("Failed to execute gluster volume get command"
+ "for volume %s" % volname)
return None
volume_option = {}
- raw_output = ret[1].split("\n")
+ raw_output = out.split("\n")
for line in raw_output[2:-1]:
match = re.search(r'^(\S+)(.*)', line.strip())
if match is None:
- tc.logger.error("gluster get volume output is not in \
- expected format")
+ tc.logger.error("gluster get volume output is not in "
+ "expected format")
return None
volume_option[match.group(1)] = match.group(2).strip()
@@ -500,26 +661,116 @@ def get_volume_option(volname, option='all', server=''):
return volume_option
-def get_volume_info(volname='all', server=''):
+def set_volume_options(volname, options, mnode=None):
+ """sets the option values for the given volume.
+
+ Args:
+ volname (str): volume name
+ options (dict): volume options in key
+ value format
+
+ Kwargs:
+ mnode (str): Node on which cmd has to be executed.
+ If None, defaults to servers[0].
+
+ Returns:
+ bool: True, if the volume option is set
+ False, on failure
+
+ Example:
+ options = {"user.cifs":"enable","user.smb":"enable"}
+ set_volume_option("testvol", options=options)
"""
- Fetches the volume information as displayed in the volume info.
+ if mnode is None:
+ mnode = tc.servers[0]
+ _rc = True
+ for option in options:
+ cmd = ("gluster volume set %s %s %s"
+ % (volname, option, options[option]))
+ ret, _, _ = tc.run(mnode, cmd)
+ if ret != 0:
+ tc.logger.error("Unable to set value %s for option %s"
+ % (options[option], option))
+ _rc = False
+ return _rc
+
+
+def volume_info(volname='all', mnode=None):
+ """Executes gluster volume info cli command
+
+ Kwargs:
+ volname (str): volume name. Defaults to 'all'
+ 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:
+ volume_status()
+ """
+ if mnode is None:
+ mnode = tc.servers[0]
+
+ cmd = "gluster volume info %s" % volname
+ return tc.run(mnode, cmd)
+
+
+def get_volume_info(volname='all', mnode=None):
+ """Fetches the volume information as displayed in the volume info.
Uses xml output of volume info and parses the into to a dict
- Returns a dict of dicts.
- -- Volume name is the first key
- -- distCount/replicaCount/Type etc are second keys
- -- The value of the each second level dict depends on the key
- -- For distCount/replicaCount etc the value is key
- -- For bricks, the value is a list of bricks (hostname:/brick_path)
+ Kwargs:
+ volname (str): volume name. Defaults to 'all'
+ mnode (str): Node on which cmd has to be executed.
+ If None, defaults to servers[0].
+
+ Returns:
+ NoneType: If there are errors
+ dict: volume info in dict of dicts
+
+ Example:
+ get_volume_info(volname="testvol")
+ >>>{'testvol': {'status': '1', 'xlators': None, 'disperseCount': '0',
+ 'bricks': {'coldBricks': {'colddisperseCount': '0',
+ 'coldarbiterCount': '0', 'coldBrickType': 'Distribute',
+ 'coldbrickCount': '4', 'numberOfBricks': '4', 'brick':
+ [{'isArbiter': '0', 'name': '10.70.47.89:/bricks/brick1/a11',
+ 'hostUuid': '7fc9015e-8134-4753-b837-54cbc6030c98'}, {'isArbiter':
+ '0', 'name': '10.70.47.118:/bricks/brick1/a21', 'hostUuid':
+ '7fc9015e-8134-4753-b837-54cbc6030c98'}, {'isArbiter': '0', 'name':
+ '10.70.47.89:/bricks/brick2/a31', 'hostUuid':
+ '7fc9015e-8134-4753-b837-54cbc6030c98'}, {'isArbiter': '0',
+ 'name': '10.70.47.118:/bricks/brick2/a41', 'hostUuid':
+ '7fc9015e-8134-4753-b837-54cbc6030c98'}], 'coldreplicaCount': '1'},
+ 'hotBricks': {'hotBrickType': 'Distribute', 'numberOfBricks': '1',
+ 'brick': [{'name': '10.70.47.89:/bricks/brick1/a12', 'hostUuid':
+ '7fc9015e-8134-4753-b837-54cbc6030c98'}], 'hotbrickCount': '1',
+ 'hotreplicaCount': '1'}}, 'type': '5', 'distCount': '1',
+ 'replicaCount': '1', 'brickCount': '5', 'options':
+ {'cluster.tier-mode': 'cache', 'performance.readdir-ahead': 'on',
+ 'features.ctr-enabled': 'on'}, 'redundancyCount': '0', 'transport':
+ '0', 'typeStr': 'Tier', 'stripeCount': '1', 'arbiterCount': '0',
+ 'id': 'ffa8a8d1-546f-4ebf-8e82-fcc96c7e4e05', 'statusStr': 'Started',
+ 'optCount': '3'}}
"""
- if server == '':
- server = tc.servers[0]
- ret = tc.run(server, "gluster volume info %s --xml" % volname, \
- verbose=False)
- if ret[0] != 0:
+ if mnode is None:
+ mnode = tc.servers[0]
+
+ cmd = "gluster volume info %s --xml" % volname
+ ret, out, _ = tc.run(mnode, cmd, verbose=False)
+ if ret != 0:
tc.logger.error("volume info returned error")
return None
- root = etree.XML(ret[1])
+ root = etree.XML(out)
volinfo = {}
for volume in root.findall("volInfo/volumes/volume"):
for elem in volume.getchildren():
@@ -527,10 +778,30 @@ def get_volume_info(volname='all', server=''):
volname = elem.text
volinfo[volname] = {}
elif elem.tag == "bricks":
- volinfo[volname]["bricks"] = []
- for el in elem.getiterator():
- if el.tag == "name":
- volinfo[volname]["bricks"].append(el.text)
+ volinfo[volname]["bricks"] = {}
+ tag_list = [x.tag for x in elem.getchildren() if x]
+ if 'brick' in tag_list:
+ volinfo[volname]["bricks"]["brick"] = []
+ for el in elem.getchildren():
+ if el.tag == 'brick':
+ brick_info_dict = {}
+ for elmt in el.getchildren():
+ brick_info_dict[elmt.tag] = elmt.text
+ (volinfo[volname]["bricks"]["brick"].
+ append(brick_info_dict))
+
+ if el.tag == "hotBricks" or el.tag == "coldBricks":
+ volinfo[volname]["bricks"][el.tag] = {}
+ volinfo[volname]["bricks"][el.tag]["brick"] = []
+ for elmt in el.getchildren():
+ if elmt.tag == 'brick':
+ brick_info_dict = {}
+ for el_brk in elmt.getchildren():
+ brick_info_dict[el_brk.tag] = el_brk.text
+ (volinfo[volname]["bricks"][el.tag]["brick"].
+ append(brick_info_dict))
+ else:
+ volinfo[volname]["bricks"][el.tag][elmt.tag] = elmt.text
elif elem.tag == "options":
volinfo[volname]["options"] = {}
for option in elem.findall("option"):
@@ -541,28 +812,138 @@ def get_volume_info(volname='all', server=''):
volinfo[volname]["options"][opt] = el.text
else:
volinfo[volname][elem.tag] = elem.text
+
+ tc.logger.debug("Volume info output: %s"
+ % pformat(volinfo, indent=10))
+
return volinfo
-def set_volume_option(volname, options, server=''):
+def sync_volume(hostname, volname="all", mnode=None):
+ """syncs the volume
+
+ Args:
+ hostname (str): host name
+
+ Kwargs:
+ volname (str): volume name. Defaults to 'all'.
+ 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:
+ sync_volume("abc.xyz.com",volname="testvol")
"""
- This module sets the option values for the given volume.
- @parameter:
- * volname - <str> name of the volume to get status.
- * option - list of <dict> volume options in key value format.
- * server - <str> (optional) name of the server to execute the volume
- status command. If not given, the function takes the
- first node from config file
- @Returns: True, on success
- False, on failure
+ if mnode is None:
+ mnode = tc.servers[0]
+
+ cmd = "gluster volume sync %s %s --mode=script" % (hostname, volname)
+ return tc.run(mnode, cmd)
+
+
+def get_subvols(volname, mnode=None):
+ """Gets the subvolumes in the 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:
+ dict: with empty list values for all keys, if volume doesn't exist
+ dict: Dictionary of subvols, value of each key is list of lists
+ containing subvols
+ Example:
+ get_subvols("testvol")
"""
- if server == '':
- server = tc.servers[0]
- _rc = True
- for option in options:
- cmd = "gluster volume set %s %s %s" % (volname, option, \
- options[option])
- ret = tc.run(server, cmd)
- if ret[0] != 0:
- _rc = False
- return _rc
+
+ subvols = {
+ 'hot_tier_subvols': [],
+ 'cold_tier_subvols': [],
+ 'volume_subvols': []
+ }
+ if mnode is None:
+ mnode = tc.servers[0]
+ volinfo = get_volume_info(volname, mnode)
+ if volinfo is not None:
+ voltype = volinfo[volname]['typeStr']
+ if voltype == 'Tier':
+ hot_tier_type = (volinfo[volname]["bricks"]
+ ['hotBricks']['hotBrickType'])
+ tmp = volinfo[volname]["bricks"]['hotBricks']["brick"]
+ hot_tier_bricks = [x["name"] for x in tmp if "name" in x]
+ if (hot_tier_type == 'Distribute'):
+ for brick in hot_tier_bricks:
+ subvols['hot_tier_subvols'].append([brick])
+
+ elif (hot_tier_type == 'Replicate' or
+ hot_tier_type == 'Distributed-Replicate'):
+ rep_count = int((volinfo[volname]["bricks"]['hotBricks']
+ ['numberOfBricks']).split("=", 1)[0].
+ split("x")[1].strip())
+ subvol_list = ([hot_tier_bricks[i:i + rep_count]
+ for i in range(0, len(hot_tier_bricks),
+ rep_count)])
+ subvols['hot_tier_subvols'] = subvol_list
+ cold_tier_type = (volinfo[volname]["bricks"]['coldBricks']
+ ['coldBrickType'])
+ tmp = volinfo[volname]["bricks"]['coldBricks']["brick"]
+ cold_tier_bricks = [x["name"] for x in tmp if "name" in x]
+ if (cold_tier_type == 'Distribute' or
+ cold_tier_type == 'Disperse'):
+ for brick in cold_tier_bricks:
+ subvols['cold_tier_subvols'].append([brick])
+
+ elif (cold_tier_type == 'Replicate' or
+ cold_tier_type == 'Distributed-Replicate'):
+ rep_count = int((volinfo[volname]["bricks"]['coldBricks']
+ ['numberOfBricks']).split("=", 1)[0].
+ split("x")[1].strip())
+ subvol_list = ([cold_tier_bricks[i:i + rep_count]
+ for i in range(0, len(cold_tier_bricks),
+ rep_count)])
+ subvols['cold_tier_subvols'] = subvol_list
+
+ elif (cold_tier_type == 'Distributed-Disperse'):
+ disp_count = sum([int(nums) for nums in
+ ((volinfo[volname]["bricks"]['coldBricks']
+ ['numberOfBricks']).split("x", 1)[1].
+ strip().split("=")[0].strip().strip("()").
+ split()) if nums.isdigit()])
+ subvol_list = [cold_tier_bricks[i:i + disp_count]
+ for i in range(0, len(cold_tier_bricks),
+ disp_count)]
+ subvols['cold_tier_subvols'] = subvol_list
+ return subvols
+
+ tmp = volinfo[volname]["bricks"]["brick"]
+ bricks = [x["name"] for x in tmp if "name" in x]
+ if voltype == 'Replicate' or voltype == 'Distributed-Replicate':
+ rep_count = int(volinfo[volname]['replicaCount'])
+ subvol_list = [bricks[i:i + rep_count]for i in range(0,
+ len(bricks),
+ rep_count)]
+ subvols['volume_subvols'] = subvol_list
+ elif voltype == 'Distribute' or voltype == 'Disperse':
+ for brick in bricks:
+ subvols['volume_subvols'].append([brick])
+
+ elif voltype == 'Distributed-Disperse':
+ disp_count = int(volinfo[volname]['disperseCount'])
+ subvol_list = [bricks[i:i + disp_count]for i in range(0,
+ len(bricks),
+ disp_count)]
+ subvols['volume_subvols'] = subvol_list
+ return subvols