summaryrefslogtreecommitdiffstats
path: root/tests/distaf/distaf_libs/distaflibs-gluster/distaflibs/gluster/volume_ops.py
diff options
context:
space:
mode:
Diffstat (limited to 'tests/distaf/distaf_libs/distaflibs-gluster/distaflibs/gluster/volume_ops.py')
-rw-r--r--tests/distaf/distaf_libs/distaflibs-gluster/distaflibs/gluster/volume_ops.py949
1 files changed, 0 insertions, 949 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
deleted file mode 100644
index 58939377939..00000000000
--- a/tests/distaf/distaf_libs/distaflibs-gluster/distaflibs/gluster/volume_ops.py
+++ /dev/null
@@ -1,949 +0,0 @@
-#!/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.
-
-
-import re
-import time
-from distaf.util import tc
-from pprint import pformat
-try:
- import xml.etree.cElementTree as etree
-except ImportError:
- import xml.etree.ElementTree as etree
-from distaflibs.gluster.mount_ops import mount_volume
-from distaflibs.gluster.gluster_init import env_setup_servers, start_glusterd
-from distaflibs.gluster.peer_ops import (peer_probe_servers,
- nodes_from_pool_list)
-
-"""
- This file contains the gluster volume operations like create volume,
- start/stop volume etc
-"""
-
-
-def create_volume(volname, mnode=None, dist=1, rep=1, stripe=1, trans='tcp',
- servers=None, disp=1, dispd=1, red=1):
- """Create the gluster volume specified configuration
- volname and distribute count are mandatory argument
- Args:
- volname(str): volume name that has to be created
-
- Kwargs:
- mnode(str): server on which command has to be execeuted,
- defaults to tc.servers[0]
- dist(int): distribute count, defaults to 1
- rep(int): replica count, defaults to 1
- stripe(int): stripe count, defaults to 1
- trans(str): transport type, defaults to tcp
- servers(list): servers on which volume has to be created,
- defaults to number of servers in pool list, if that is None,
- then takes tc.servers
- disp(int): disperse count, defaults to 1
- dispd(int): disperse-data count, defaults to 1
- red(int): rdundancy count, defaults to 1
-
- 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.
-
- (-1, '', ''): If not enough bricks are available to create volume.
- (ret, out, err): As returned by volume create command execution.
-
- Example:
- create_volume(volname)
- """
- if servers is None:
- servers = nodes_from_pool_list()
- if not servers:
- servers = tc.servers[:]
- if mnode is None:
- mnode = tc.servers[0]
- dist = int(dist)
- rep = int(rep)
- stripe = int(stripe)
- disp = int(disp)
- dispd = int(dispd)
- red = int(red)
- dispc = 1
-
- if disp != 1 and dispd != 1:
- tc.logger.error("volume can't have both disperse and disperse-data")
- return (-1, None, None)
- if disp != 1:
- dispc = int(disp)
- elif dispd != 1:
- dispc = int(dispd) + int(red)
-
- number_of_bricks = dist * rep * stripe * dispc
- replica = stripec = disperse = disperse_data = redundancy = ''
-
- from distaflibs.gluster.lib_utils import form_bricks_path
- bricks_path = form_bricks_path(number_of_bricks, servers[:],
- mnode, volname)
- if bricks_path is None:
- tc.logger.error("number of bricks required are greater than "
- "unused bricks")
- return (-1, '', '')
-
- if rep != 1:
- replica = "replica %d" % rep
- if stripe != 1:
- stripec = "stripe %d" % stripe
- ttype = "transport %s" % trans
- if disp != 1:
- disperse = "disperse %d" % disp
- redundancy = "redundancy %d" % red
- elif dispd != 1:
- disperse_data = "disperse-data %d" % dispd
- redundancy = "redundancy %d" % red
-
- ret = tc.run(mnode, "gluster volume create %s %s %s %s %s %s %s %s "
- "--mode=script" % (volname, replica, stripec, disperse,
- disperse_data, redundancy, ttype,
- bricks_path))
-
- return ret
-
-
-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 is None:
- mnode = tc.servers[0]
- frce = ''
- if force:
- frce = 'force'
- cmd = "gluster volume start %s %s --mode=script" % (volname, frce)
- return tc.run(mnode, cmd)
-
-
-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 is None:
- mnode = tc.servers[0]
- frce = ''
- if force:
- frce = 'force'
- cmd = "gluster volume stop %s %s --mode=script" % (volname, frce)
- return tc.run(mnode, cmd)
-
-
-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 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
-
- 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]
- except KeyError:
- pass
- for brick in bricks:
- node, vol_dir = brick.split(":")
- ret = tc.run(node, "rm -rf %s" % vol_dir)
-
- return True
-
-
-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 is None:
- mnode = tc.servers[0]
- frce = ''
- if force:
- frce = 'force'
- cmd = "gluster volume reset %s %s --mode=script" % (volname, frce)
- return tc.run(mnode, cmd)
-
-
-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
-
- 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")
- """
- from distaflibs.gluster.snap_ops import snap_delete_by_volumename
-
- if mnode is None:
- mnode = tc.servers[0]
-
- 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
-
- ret, _, _ = stop_volume(volname, mnode, True)
- if ret != 0:
- tc.logger.error("Failed to stop volume %s" % volname)
- return False
-
- ret = delete_volume(volname, mnode)
- if not ret:
- tc.logger.error("Unable to cleanup the volume %s" % volname)
- return False
- return True
-
-
-def setup_vol(volname, mnode=None, dist=1, rep=1, dispd=1, red=1,
- stripe=1, trans="tcp", servers=None):
- """
- Setup a gluster volume for testing.
- It first formats the back-end bricks and then creates a
- trusted storage pool by doing peer probe. And then it creates
- a volume of specified configuration.
-
- When the volume is created, it sets a global flag to indicate
- that the volume is created. If another testcase calls this
- function for the second time with same volume name, the function
- checks for the flag and if found, will return True.
- Args:
- volname(str): volume name that has to be created
-
- Kwargs:
- mnode(str): server on which command has to be execeuted,
- defaults to tc.servers[0]
- dist(int): distribute count, defaults to 1
- rep(int): replica count, defaults to 1
- stripe(int): stripe count, defaults to 1
- trans(str): transport type, defaults to tcp
- servers(list): servers on which volume has to be created,
- defaults to number of servers in pool list, if that is None,
- then takes tc.servers
- disp(int): disperse count, defaults to 1
- dispd(int): disperse-data count, defaults to 1
- red(int): rdundancy count, defaults to 1
-
- Returns:
- bool: True on success and False for failure.
- """
- if servers is None:
- servers = tc.servers[:]
- if mnode is None:
- mnode = tc.servers[0]
- volinfo = get_volume_info(mnode=mnode)
- if volinfo is not None and volname in volinfo.keys():
- tc.logger.debug("volume %s already exists in %s. Returning..." \
- % (volname, servers[0]))
- return True
- ret = env_setup_servers(servers=servers)
- if not ret:
- tc.logger.error("Formatting backend bricks failed. Aborting...")
- return False
- ret = start_glusterd(servers)
- if not ret:
- tc.logger.error("glusterd did not start in at least one server")
- return False
- time.sleep(5)
- ret = peer_probe_servers(servers[1:], mnode=mnode)
- if not ret:
- tc.logger.error("Unable to peer probe one or more machines")
- return False
- if rep != 1 and dispd != 1:
- tc.logger.warning("Both replica count and disperse count is specified")
- tc.logger.warning("Ignoring the disperse and using the replica count")
- dispd = 1
- red = 1
- ret = create_volume(volname, mnode, dist, rep, stripe, trans, servers,
- dispd=dispd, red=red)
- if ret[0] != 0:
- tc.logger.error("Unable to create volume %s" % volname)
- return False
- time.sleep(2)
- ret = start_volume(volname, mnode)
- if not ret:
- tc.logger.error("volume start %s failed" % volname)
- return False
- if tc.global_config["gluster"]["cluster_config"]["nfs_ganesha"]["enable"]:
- from distaflibs.gluster.ganesha import vol_set_ganesha
- ret = vol_set_ganesha(volname)
- if not ret:
- tc.logger.error("failed to set the ganesha option for %s" % volname)
- return False
- tc.global_flag[volname] = True
- 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")
- root_vol = _parse_volume_status_xml(element)
- if root_vol is not None:
- return root_vol
-
-
-def parse_xml(tag_obj):
- """
- 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:
- if re.search(r'\n\s+', tag.text) is not None:
- port_dict = {}
- port_dict = parse_xml(tag)
- node_dict[tag.tag] = port_dict
- else:
- node_dict[tag.tag] = tag.text
- return node_dict
-
-
-def get_volume_status(volname='all', service='', options='', mnode=None):
- """
- This module gets the status of all or specified volume(s)/brick
-
- 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 is None:
- mnode = tc.servers[0]
-
- cmd = "gluster vol status %s %s %s --xml" % (volname, service, options)
-
- ret, out, _ = tc.run(mnode, cmd)
- if ret != 0:
- tc.logger.error("Failed to execute gluster volume status command")
- return None
-
- 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")
- return None
-
- vol_status = {}
- 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
- if options == 'tasks':
- tasks = volume.findall("tasks")
- for each_task in tasks:
- tmp_dict3 = parse_xml(each_task)
- node_name = 'task_status'
- if 'task' in tmp_dict3.keys():
- if node_name in tmp_dict2.keys():
- tmp_dict2[node_name].append(tmp_dict3['task'])
- else:
- tmp_dict2[node_name] = [tmp_dict3['task']]
- else:
- tmp_dict2[node_name] = [tmp_dict3]
- else:
- 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:
- tmp_dict3[node_dict["hostname"]] = node_dict
- 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:
- tmp_dict1[node_name] = [tmp_dict3]
-
- tmp_dict4 = {}
- for item in tmp_dict1[node_name]:
- for key, val in item.items():
- tmp_dict4[key] = val
- tmp_dict2[node_name] = tmp_dict4
-
- vol_status[vol_name[0]] = tmp_dict2
- tc.logger.debug("Volume status output: %s"
- % pformat(vol_status, indent=10))
- return vol_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
- 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 mnode is None:
- mnode = tc.servers[0]
-
- cmd = "gluster volume get %s %s" % (volname, option)
- 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 = 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")
- return None
-
- volume_option[match.group(1)] = match.group(2).strip()
-
- return volume_option
-
-
-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)
- """
- 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
-
- 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 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(out)
- volinfo = {}
- for volume in root.findall("volInfo/volumes/volume"):
- for elem in volume.getchildren():
- if elem.tag == "name":
- volname = elem.text
- volinfo[volname] = {}
- elif elem.tag == "bricks":
- 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"):
- for el in option.getchildren():
- if el.tag == "name":
- opt = el.text
- if el.tag == "value":
- 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 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")
- """
- 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")
- """
-
- 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