summaryrefslogtreecommitdiffstats
path: root/glustolibs-gluster/glustolibs/gluster/brickmux_libs.py
blob: cb82d84347c615bd41a5977a2aa90aae046d2869 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
#  Copyright (C) 2020 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: 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:
            try:
                server = server_ip.next()  # Python 2
            except AttributeError:
                server = next(server_ip)  # Python 3
            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