From d60d5c42692c547608c9a45f879d67e9c79e10ca Mon Sep 17 00:00:00 2001 From: Bala Konda Reddy M Date: Fri, 31 Jan 2020 18:23:58 +0530 Subject: [Lib] Library for multi volume creation Earlier, brick creation is carried out based on the difference of used and unused bricks. This is a bottleneck for implementing brick multiplexing testcases. Moreover we can't create more than 10 volumes. With this library, implementing a way to create bricks on top of the existing servers in a cyclic way to have equal number of bricks on each brick partition on each server Added paramter in setup_volume function, if multi_vol flag is set it will fetch bricks using cyclic manner using (form_bricks_for_multi_vol) otherwise it will fetch using old mechanism. Added bulk_volume_creation function, to create multiple volumes the user has specified. Change-Id: I2103ec6ce2be4e091e0a96b18220d5e3502284a0 Signed-off-by: Bala Konda Reddy M --- .../glustolibs/gluster/brickmux_libs.py | 146 +++++++++++++++++++++ 1 file changed, 146 insertions(+) create mode 100644 glustolibs-gluster/glustolibs/gluster/brickmux_libs.py (limited to 'glustolibs-gluster/glustolibs/gluster/brickmux_libs.py') diff --git a/glustolibs-gluster/glustolibs/gluster/brickmux_libs.py b/glustolibs-gluster/glustolibs/gluster/brickmux_libs.py new file mode 100644 index 000000000..1206b4682 --- /dev/null +++ b/glustolibs-gluster/glustolibs/gluster/brickmux_libs.py @@ -0,0 +1,146 @@ +# Copyright (C) 2020 Red Hat, Inc. +# +# 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: Module for Brick multiplexing realted helper functions. +""" + +from itertools import cycle +try: + from itertools import zip_longest +except ImportError: + from itertools import izip_longest as zip_longest + +from glusto.core import Glusto as g +from glustolibs.gluster.volume_ops import get_volume_list +from glustolibs.gluster.lib_utils import get_servers_bricks_dict + + +def get_all_bricks_from_servers_multivol(servers, servers_info): + """ + Form list of all the bricks to create/add-brick from the given + servers and servers_info + + Args: + servers (list): List of servers in the storage pool. + servers_info (dict): Information about all servers. + + Returns: + brickCount (int): Number of bricks available from the servers. + bricks_list (list): List of all bricks from the servers provided. + + example : + servers_info = { + 'abc.lab.eng.xyz.com': { + 'host': 'abc.lab.eng.xyz.com', + 'brick_root': '/bricks', + 'devices': ['/dev/vdb', '/dev/vdc', '/dev/vdd', '/dev/vde'] + }, + 'def.lab.eng.xyz.com':{ + 'host': 'def.lab.eng.xyz.com', + 'brick_root': '/bricks', + 'devices': ['/dev/vdb', '/dev/vdc', '/dev/vdd', '/dev/vde'] + } + } + """ + if not isinstance(servers, list): + servers = [servers] + + brickCount, bricks_list = 0, [] + + servers_bricks = get_servers_bricks_dict(servers, servers_info) + server_ip = cycle(servers_bricks.keys()) + + for item in list(zip_longest(*list(servers_bricks.values()))): + for brick in item: + server = server_ip.next() + if brick: + bricks_list.append(server + ":" + brick) + brickCount += 1 + return brickCount, bricks_list + + +def get_current_brick_index(mnode): + """ + Get the brick current index from the node of the cluster. + + Args: + mnode (str): Node on which commands has to be executed. + + Returns: + NoneType: If there are any errors + int: Count of the bricks in the cluster. + """ + ret, brick_index, err = g.run(mnode, "gluster volume info | egrep " + "\"^Brick[0-9]+\" | grep -v \"ss_brick\"") + if ret: + g.log.error("Error in getting bricklist using gluster v info %s" % err) + return None + + g.log.info("brick_index is ", brick_index) + return len(brick_index.splitlines()) + + +def form_bricks_for_multivol(mnode, volname, number_of_bricks, servers, + servers_info): + """ + Forms brics list for volume create/add-brick given the number_of_bricks + servers, servers_info, for multiple volume cluster and for brick multiplex + enabled cluster. + + Args: + mnode (str): Node on which commands has to be executed. + volname (str): Volume name for which we require brick-list + number_of_bricks (int): The number of bricks for which brick list + has to be created. + servers (str|list): A server|List of servers from which the bricks + needs to be selected for creating the brick list. + servers_info (dict): Dict of server info of each servers. + + Returns: + list: List of bricks to use with volume create. + Nonetype: If unable to fetch the brick list + + """ + if not isinstance(servers, list): + servers = [servers] + + brick_index, brick_list_for_volume = 0, [] + + # Importing get_all_bricks() from bricks_libs to avoid cyclic imports + from glustolibs.gluster.brick_libs import get_all_bricks + + # Get all volume list present in the cluster from mnode + current_vol_list = get_volume_list(mnode) + for volume in current_vol_list: + brick_index = brick_index + len(get_all_bricks(mnode, volume)) + g.log.info("current brick_index %s" % brick_index) + + # Get all bricks_count and bricks_list + all_brick_count, bricks_list = get_all_bricks_from_servers_multivol( + servers, servers_info) + if not (all_brick_count > 1): + g.log.error("Unable to get the bricks present in the specified" + "servers") + return None + + for num in range(number_of_bricks): + brick = brick_index % all_brick_count + brick_list_for_volume.append("%s/%s_brick%d" % (bricks_list[brick], + volname, brick_index)) + brick_index += 1 + + return brick_list_for_volume -- cgit