From eaf3d4136d6dd1ef00a7cef23f9338b03783dd43 Mon Sep 17 00:00:00 2001 From: Shubhendu Tripathi Date: Tue, 1 Apr 2014 15:12:50 +0530 Subject: gluster-nagios-common: Added storage utils module Introduced storage device utils module Change-Id: I738b46b0750deaf91b896a8edab07b5f1a692ddb Signed-off-by: Shubhendu Tripathi Reviewed-on: https://code.engineering.redhat.com/gerrit/22254 Reviewed-by: Sahina Bose Tested-by: Sahina Bose --- glusternagios/Makefile.am | 1 + glusternagios/storage.py | 253 ++++++++++++++++++++++++++++++ glusternagios/utils.py | 11 -- tests/test_storage.py | 391 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 645 insertions(+), 11 deletions(-) create mode 100755 glusternagios/storage.py create mode 100644 tests/test_storage.py diff --git a/glusternagios/Makefile.am b/glusternagios/Makefile.am index 7f46e08..6698600 100644 --- a/glusternagios/Makefile.am +++ b/glusternagios/Makefile.am @@ -2,5 +2,6 @@ dist_glusternagioscommonpylib_PYTHON = \ __init__.py \ glustercli.py \ hostname.py \ + storage.py \ utils.py \ $(NULL) diff --git a/glusternagios/storage.py b/glusternagios/storage.py new file mode 100755 index 0000000..3371d4e --- /dev/null +++ b/glusternagios/storage.py @@ -0,0 +1,253 @@ +# Copyright 2014 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 +# (at your option) 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 +# +# Refer to the README and COPYING files for full details of the license +# + +import os + +import utils +from utils import CommandPath +import glustercli + +lvsCmdPath = CommandPath("lvs", + "/sbin/lvs", + ) +vgsCmdPath = CommandPath("vgs", + "/sbin/vgs", + ) +pvsCmdPath = CommandPath("pvs", + "/sbin/pvs") + + +# Class for exception definition +class ExecCmdFailedException(Exception): + message = "command execution failed" + + def __init__(self, rc=0, out=(), err=()): + self.rc = rc + self.out = out + self.err = err + + def __str__(self): + o = '\n'.join(self.out) + e = '\n'.join(self.err) + if o and e: + m = o + '\n' + e + else: + m = o or e + + s = self.message + if m: + s += '\nerror: ' + m + if self.rc: + s += '\nreturn code: %s' % self.rc + return s + + +# Creates a dict out of the given string +def _reduceToDict(out): + for line in out: + yield dict(pair.split('=') for pair in line.strip().split('^')) + + +# Parses the lvs command output and returns the required dictionary +def _parseLvs(output): + return dict((x['LVM2_LV_PATH'], x) for x in _reduceToDict(output)) + + +def _getLvsCmd(): + return [lvsCmdPath.cmd] + (" --unquoted --noheading " + + "--nameprefixes --separator ^ " + + "--nosuffix --units m -o " + + "lv_all,vg_name").split() + + +def _getVgsCmd(): + return [vgsCmdPath.cmd] + (" --unquoted --noheading " + + "--nameprefixes --separator ^ " + + "--nosuffix --units m -o " + + "vg_all,lv_path").split() + + +def _getPvsCmd(): + return [pvsCmdPath.cmd] + (" --unquoted --noheading " + + "--nameprefixes --separator ^ " + + "--nosuffix --units m -o " + + "pv_all,vg_name").split() + + +def _getLvDetailsCmd(): + return [pvsCmdPath.cmd] + (" --unquoted --noheading " + + "--nameprefixes --separator ^ " + + "--nosuffix --units m -o " + + "vg_name,pv_name,lv_name").split() + + +# Gets the list of logical volumes +def getLvs(): + rc, out, err = utils.execCmd(_getLvsCmd()) + if rc: + raise ExecCmdFailedException(err=[str(err)]) + + return _parseLvs(out) + + +# Parses the vgs coammnd output and returns the required dictionary +def _parseVgs(out): + def _makeVgDict(x, y): + y['LVM2_LV_PATH'] = [y['LVM2_LV_PATH']] if y['LVM2_LV_PATH'] else [] + if y['LVM2_VG_NAME'] in x: + x[y['LVM2_VG_NAME']]['LVM2_LV_PATH'] += y['LVM2_LV_PATH'] + else: + x[y['LVM2_VG_NAME']] = y + return x + + return reduce(_makeVgDict, _reduceToDict(out), {}) + + +# Gets the list of volume groups +def getVgs(): + rc, out, err = utils.execCmd(_getVgsCmd()) + if rc: + raise ExecCmdFailedException(err=[str(err)]) + + return _parseVgs(out) + + +# Parses the output of pvs command and returns the required dictionary +def _parsePvs(out): + return dict((x['LVM2_PV_NAME'], x) for x in _reduceToDict(out)) + + +# Gets the list of physical volumes +def getPvs(): + rc, out, err = utils.execCmd(_getPvsCmd()) + if rc: + raise ExecCmdFailedException(err=[str(err)]) + + return _parsePvs(out) + + +# Returns the mount point for the given path +def _getMountPoint(path): + path = os.path.abspath(path) + while not os.path.ismount(path): + path = os.path.dirname(path) + + return path + + +# Gets the lv details +def _getLvDetails(): + rc, out, err = utils.execCmd(_getLvDetailsCmd()) + if rc: + raise ExecCmdFailedException(err=[str(err)]) + + return dict((x['LVM2_LV_NAME'], x) for x in _reduceToDict(out)) + + +# Gets the brickwise mount points +def _getBrickMountPoints(): + mount_points = {} + volumeInfo = glustercli.volumeInfo() + for key in volumeInfo.keys(): + volume = volumeInfo[key] + bricks = volume['bricks'] + for brick in bricks: + mount_points[brick] = _getMountPoint(brick.split(":")[1]) + + return mount_points + + +# Gets the list of all the proc mounts +def _getProcMounts(): + mounts = {} + with open('/proc/mounts') as f: + for line in f: + arr = line.split() + mounts[arr[0]] = arr[1] + + return mounts + + +# Gets the list of bricks for a given disk +def getBricksForDisk(diskName): + # Get all the lv details + lv_dict = _getLvDetails() + + # Reduce the LVs for the give device + validLvs = {} + for key in lv_dict.keys(): + if lv_dict[key]['LVM2_PV_NAME'] == diskName: + validLvs[key] = lv_dict[key] + + # Get the brickwise mount points + brick_mount_points = _getBrickMountPoints() + + # Get the list of all the mount points + procmounts = _getProcMounts() + + # Get the mount points to find bricks for + mount_points_to_check = [] + for key in validLvs.keys(): + searchname = "%s-%s" % (validLvs[key]['LVM2_VG_NAME'], + validLvs[key]['LVM2_LV_NAME']) + for mount in procmounts.keys(): + if mount.endswith(searchname): + mount_points_to_check.append(procmounts[mount]) + + # Get the list of bricks + bricks_list = [] + for key in brick_mount_points.keys(): + if brick_mount_points[key] in mount_points_to_check: + bricks_list.append(key) + + return bricks_list + + +# Gets the brick's device name +def _getBrickDeviceName(brickName): + brickDevices = {} + volStatus = glustercli.volumeStatus("all", option="detail") + bricks = volStatus['bricks'] + for brick in bricks: + brick_dir = brick['brick'] + brickDevices[brick_dir] = brick['device'] + + if brickName in brickDevices.keys(): + return brickDevices[brickName] + else: + return "" + + +# Gets the list of disks participating in the given brick +def getDisksForBrick(brickName, deviceName=None): + # Get the brick device name + if deviceName is None: + deviceName = _getBrickDeviceName(brickName) + + # Get the lv details + lv_dict = _getLvDetails() + + # Get the disk name for the brick + for key in lv_dict.keys(): + tmp_str = "%s-%s" % (lv_dict[key]['LVM2_VG_NAME'], + lv_dict[key]['LVM2_LV_NAME']) + if deviceName.endswith(tmp_str): + return lv_dict[key]['LVM2_PV_NAME'] + + return "" diff --git a/glusternagios/utils.py b/glusternagios/utils.py index 047fccf..a46811d 100644 --- a/glusternagios/utils.py +++ b/glusternagios/utils.py @@ -105,17 +105,6 @@ setsidCmdPath = CommandPath("setsid", sudoCmdPath = CommandPath("sudo", "/usr/bin/sudo", ) -lvsCmdPath = CommandPath("lvs", - "/sbin/lvs", - ) -vgsCmdPath = CommandPath("vgs", - "/sbin/vgs", - ) -pvsCmdPath = CommandPath("pvs", - "/sbin/pvs", - ) -hostnameCmdPath = CommandPath("hostname", "/bin/hostname", ) -glusterCmdPath = CommandPath("gluster", "/usr/sbin/gluster") # Buffsize is 1K because I tested it on some use cases and 1K was fastest. If # you find this number to be a bottleneck in any way you are welcome to change # it diff --git a/tests/test_storage.py b/tests/test_storage.py new file mode 100644 index 0000000..3a15cf1 --- /dev/null +++ b/tests/test_storage.py @@ -0,0 +1,391 @@ +# +# Copyright 2014 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 +# (at your option) 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 +# +# Refer to the README and COPYING files for full details of the license +# + +import mock + +from testrunner import GlusterNagiosTestCase as TestCaseBase +from glusternagios import storage +import glusternagios + + +class TestStorageUtils(TestCaseBase): + @mock.patch('glusternagios.storage.utils') + def testGetLvs(self, mock_utils): + tmp_str = ["LVM2_LV_UUID=zjuuHG-HajL-PXxm-fjlL-5i00-EUnV-Wd2qL3^" + "LVM2_LV_NAME=lv_root^" + "LVM2_LV_PATH=/dev/vg_shubhnd/lv_root^" + "LVM2_LV_ATTR=-wi-ao---^" + "LVM2_LV_MAJOR=-1^" + "LVM2_LV_MINOR=-1^" + "LVM2_LV_READ_AHEAD=auto^" + "LVM2_LV_KERNEL_MAJOR=253^" + "LVM2_LV_KERNEL_MINOR=0^" + "LVM2_LV_KERNEL_READ_AHEAD=0.12^" + "LVM2_LV_SIZE=46728.00^" + "LVM2_LV_METADATA_SIZE=^" + "LVM2_SEG_COUNT=1^" + "LVM2_ORIGIN=^" + "LVM2_ORIGIN_SIZE=0^" + "LVM2_DATA_PERCENT=^" + "LVM2_SNAP_PERCENT=^" + "LVM2_METADATA_PERCENT=^" + "LVM2_COPY_PERCENT=^" + "LVM2_SYNC_PERCENT=^" + "LVM2_MOVE_PV=^" + "LVM2_CONVERT_LV=^" + "LVM2_MIRROR_LOG=^" + "LVM2_DATA_LV=^" + "LVM2_METADATA_LV=^" + "LVM2_POOL_LV=^" + "LVM2_LV_TAGS=^" + "LVM2_LV_TIME=2014-03-14 04:27:56 +0530^" + "LVM2_LV_HOST=shubh-nd.redhat.com^" + "LVM2_MODULES=^" + "LVM2_VG_NAME=vg_shubhnd", + "LVM2_LV_UUID=klTthp-BXN8-9loo-UUo9-Y2lB-6azb-X9fFdH^" + "LVM2_LV_NAME=lv_swap^" + "LVM2_LV_PATH=/dev/vg_shubhnd/lv_swap^" + "LVM2_LV_ATTR=-wi-ao---^" + "LVM2_LV_MAJOR=-1^" + "LVM2_LV_MINOR=-1^" + "LVM2_LV_READ_AHEAD=auto^" + "LVM2_LV_KERNEL_MAJOR=253^" + "LVM2_LV_KERNEL_MINOR=1^" + "LVM2_LV_KERNEL_READ_AHEAD=0.12^" + "LVM2_LV_SIZE=3968.00^" + "LVM2_LV_METADATA_SIZE=^" + "LVM2_SEG_COUNT=1^" + "LVM2_ORIGIN=^" + "LVM2_ORIGIN_SIZE=0^" + "LVM2_DATA_PERCENT=^" + "LVM2_SNAP_PERCENT=^" + "LVM2_METADATA_PERCENT=^" + "LVM2_COPY_PERCENT=^" + "LVM2_SYNC_PERCENT=^" + "LVM2_MOVE_PV=^" + "LVM2_CONVERT_LV=^" + "LVM2_MIRROR_LOG=^" + "LVM2_DATA_LV=^" + "LVM2_METADATA_LV=^" + "LVM2_POOL_LV=^" + "LVM2_LV_TAGS=^" + "LVM2_LV_TIME=2014-03-14 04:28:01 +0530^" + "LVM2_LV_HOST=shubh-nd.redhat.com^" + "LVM2_MODULES=^" + "LVM2_VG_NAME=vg_shubhnd"] + mock_utils.execCmd.return_value = (0, tmp_str, "") + ret_val = glusternagios.storage.getLvs() + value_to_verify = {'/dev/vg_shubhnd/lv_root': + {'LVM2_SYNC_PERCENT': '', + 'LVM2_LV_METADATA_SIZE': '', + 'LVM2_LV_ATTR': '-wi-ao---', + 'LVM2_MIRROR_LOG': '', + 'LVM2_LV_KERNEL_MINOR': '0', + 'LVM2_LV_SIZE': '46728.00', + 'LVM2_LV_MAJOR': '-1', + 'LVM2_ORIGIN_SIZE': '0', + 'LVM2_LV_TIME': '2014-03-14 04:27:56 +0530', + 'LVM2_METADATA_PERCENT': '', + 'LVM2_POOL_LV': '', + 'LVM2_COPY_PERCENT': '', + 'LVM2_CONVERT_LV': '', + 'LVM2_LV_KERNEL_READ_AHEAD': '0.12', + 'LVM2_LV_NAME': 'lv_root', + 'LVM2_LV_HOST': 'shubh-nd.redhat.com', + 'LVM2_LV_UUID': + 'zjuuHG-HajL-PXxm-fjlL-5i00-EUnV-Wd2qL3', + 'LVM2_LV_MINOR': '-1', + 'LVM2_DATA_PERCENT': '', + 'LVM2_LV_KERNEL_MAJOR': '253', + 'LVM2_LV_TAGS': '', + 'LVM2_MODULES': '', + 'LVM2_VG_NAME': 'vg_shubhnd', + 'LVM2_METADATA_LV': '', + 'LVM2_LV_PATH': '/dev/vg_shubhnd/lv_root', + 'LVM2_DATA_LV': '', + 'LVM2_LV_READ_AHEAD': 'auto', + 'LVM2_SNAP_PERCENT': '', + 'LVM2_MOVE_PV': '', + 'LVM2_ORIGIN': '', + 'LVM2_SEG_COUNT': '1'}, + '/dev/vg_shubhnd/lv_swap': + {'LVM2_SYNC_PERCENT': '', + 'LVM2_LV_METADATA_SIZE': '', + 'LVM2_LV_ATTR': '-wi-ao---', + 'LVM2_MIRROR_LOG': '', + 'LVM2_LV_KERNEL_MINOR': '1', + 'LVM2_LV_SIZE': '3968.00', + 'LVM2_LV_MAJOR': '-1', + 'LVM2_ORIGIN_SIZE': '0', + 'LVM2_LV_TIME': '2014-03-14 04:28:01 +0530', + 'LVM2_METADATA_PERCENT': '', + 'LVM2_POOL_LV': '', + 'LVM2_COPY_PERCENT': '', + 'LVM2_CONVERT_LV': '', + 'LVM2_LV_KERNEL_READ_AHEAD': '0.12', + 'LVM2_LV_NAME': 'lv_swap', + 'LVM2_LV_HOST': 'shubh-nd.redhat.com', + 'LVM2_LV_UUID': + 'klTthp-BXN8-9loo-UUo9-Y2lB-6azb-X9fFdH', + 'LVM2_LV_MINOR': '-1', + 'LVM2_DATA_PERCENT': '', + 'LVM2_LV_KERNEL_MAJOR': '253', + 'LVM2_LV_TAGS': '', + 'LVM2_MODULES': '', + 'LVM2_VG_NAME': 'vg_shubhnd', + 'LVM2_METADATA_LV': '', + 'LVM2_LV_PATH': '/dev/vg_shubhnd/lv_swap', + 'LVM2_DATA_LV': '', + 'LVM2_LV_READ_AHEAD': 'auto', + 'LVM2_SNAP_PERCENT': '', + 'LVM2_MOVE_PV': '', + 'LVM2_ORIGIN': '', + 'LVM2_SEG_COUNT': '1'}} + self.assertEquals(ret_val, value_to_verify) + + @mock.patch('glusternagios.storage.utils') + def testGetVgs(self, mock_utils): + tmp_str = ["LVM2_VG_FMT=lvm2^" + "LVM2_VG_UUID=sTDsBh-DOc7-JR3y-RPHb-yz4R-aWP7-yZWQ0E^" + "LVM2_VG_NAME=vg_shubhnd^" + "LVM2_VG_ATTR=wz--n-^" + "LVM2_VG_SIZE=50696.00^" + "LVM2_VG_FREE=0^" + "LVM2_VG_SYSID=^" + "LVM2_VG_EXTENT_SIZE=4.00^" + "LVM2_VG_EXTENT_COUNT=12674^" + "LVM2_VG_FREE_COUNT=0^" + "LVM2_MAX_LV=0^" + "LVM2_MAX_PV=0^" + "LVM2_PV_COUNT=1^" + "LVM2_LV_COUNT=2^" + "LVM2_SNAP_COUNT=0^" + "LVM2_VG_SEQNO=3^" + "LVM2_VG_TAGS=^" + "LVM2_VG_MDA_COUNT=1^" + "LVM2_VG_MDA_USED_COUNT=1^" + "LVM2_VG_MDA_FREE=0.50^" + "LVM2_VG_MDA_SIZE=1.00^" + "LVM2_VG_MDA_COPIES=unmanaged^" + "LVM2_LV_PATH=/dev/vg_shubhnd/lv_root", + "LVM2_VG_FMT=lvm2^" + "LVM2_VG_UUID=sTDsBh-DOc7-JR3y-RPHb-yz4R-aWP7-yZWQ0E^" + "LVM2_VG_NAME=vg_shubhnd^" + "LVM2_VG_ATTR=wz--n-^" + "LVM2_VG_SIZE=50696.00^" + "LVM2_VG_FREE=0^" + "LVM2_VG_SYSID=^" + "LVM2_VG_EXTENT_SIZE=4.00^" + "LVM2_VG_EXTENT_COUNT=12674^" + "LVM2_VG_FREE_COUNT=0^" + "LVM2_MAX_LV=0^" + "LVM2_MAX_PV=0^" + "LVM2_PV_COUNT=1^" + "LVM2_LV_COUNT=2^" + "LVM2_SNAP_COUNT=0^" + "LVM2_VG_SEQNO=3^" + "LVM2_VG_TAGS=^" + "LVM2_VG_MDA_COUNT=1^" + "LVM2_VG_MDA_USED_COUNT=1^" + "LVM2_VG_MDA_FREE=0.50^" + "LVM2_VG_MDA_SIZE=1.00^" + "LVM2_VG_MDA_COPIES=unmanaged^" + "LVM2_LV_PATH=/dev/vg_shubhnd/lv_swap"] + mock_utils.execCmd.return_value = (0, tmp_str, "") + ret_val = glusternagios.storage.getVgs() + value_to_verify = {'vg_shubhnd': + {'LVM2_VG_EXTENT_SIZE': '4.00', + 'LVM2_VG_MDA_COUNT': '1', + 'LVM2_VG_SYSID': '', + 'LVM2_VG_ATTR': 'wz--n-', + 'LVM2_VG_UUID': + 'sTDsBh-DOc7-JR3y-RPHb-yz4R-aWP7-yZWQ0E', + 'LVM2_VG_MDA_COPIES': 'unmanaged', + 'LVM2_VG_MDA_FREE': '0.50', + 'LVM2_VG_TAGS': '', + 'LVM2_VG_FMT': 'lvm2', + 'LVM2_PV_COUNT': '1', + 'LVM2_VG_EXTENT_COUNT': '12674', + 'LVM2_VG_MDA_SIZE': '1.00', + 'LVM2_SNAP_COUNT': '0', + 'LVM2_LV_COUNT': '2', + 'LVM2_VG_NAME': 'vg_shubhnd', + 'LVM2_VG_MDA_USED_COUNT': '1', + 'LVM2_VG_FREE': '0', + 'LVM2_VG_SEQNO': '3', + 'LVM2_LV_PATH': + ['/dev/vg_shubhnd/lv_root', + '/dev/vg_shubhnd/lv_swap'], + 'LVM2_VG_FREE_COUNT': '0', + 'LVM2_MAX_PV': '0', + 'LVM2_MAX_LV': '0', + 'LVM2_VG_SIZE': '50696.00'}} + self.assertEquals(ret_val, value_to_verify) + + @mock.patch('glusternagios.storage.utils') + def testGetPvs(self, mock_utils): + tmp_str = ["LVM2_PV_FMT=lvm2^" + "LVM2_PV_UUID=NF1uv0-eXJM-YJrn-Rc7b-Z2nw-E1Ly-3S24zn^" + "LVM2_DEV_SIZE=50699.00^" + "LVM2_PV_NAME=/dev/vda2^" + "LVM2_PV_MDA_FREE=0.50^" + "LVM2_PV_MDA_SIZE=1.00^" + "LVM2_PE_START=1.00^" + "LVM2_PV_SIZE=50696.00^" + "LVM2_PV_FREE=0^" + "LVM2_PV_USED=50696.00^" + "LVM2_PV_ATTR=a--^" + "LVM2_PV_PE_COUNT=12674^" + "LVM2_PV_PE_ALLOC_COUNT=12674^" + "LVM2_PV_TAGS=^" + "LVM2_PV_MDA_COUNT=1^" + "LVM2_PV_MDA_USED_COUNT=1^" + "LVM2_VG_NAME=vg_shubhnd"] + mock_utils.execCmd.return_value = (0, tmp_str, "") + ret_val = glusternagios.storage.getPvs() + value_to_verify = {'/dev/vda2': + {'LVM2_PV_MDA_USED_COUNT': '1', + 'LVM2_PV_UUID': + 'NF1uv0-eXJM-YJrn-Rc7b-Z2nw-E1Ly-3S24zn', + 'LVM2_PE_START': '1.00', + 'LVM2_DEV_SIZE': '50699.00', + 'LVM2_PV_NAME': '/dev/vda2', + 'LVM2_PV_FMT': 'lvm2', + 'LVM2_PV_MDA_COUNT': '1', + 'LVM2_PV_MDA_FREE': '0.50', + 'LVM2_PV_TAGS': '', + 'LVM2_PV_FREE': '0', + 'LVM2_PV_SIZE': '50696.00', + 'LVM2_PV_PE_ALLOC_COUNT': '12674', + 'LVM2_PV_MDA_SIZE': '1.00', + 'LVM2_VG_NAME': 'vg_shubhnd', + 'LVM2_PV_USED': '50696.00', + 'LVM2_PV_ATTR': 'a--', + 'LVM2_PV_PE_COUNT': '12674'}} + self.assertEquals(ret_val, value_to_verify) + + @mock.patch('glusternagios.storage._getMountPoint') + @mock.patch('glusternagios.storage._getProcMounts') + @mock.patch('glusternagios.storage.glustercli.utils') + @mock.patch('glusternagios.storage._getLvDetails') + def testGetBricksForDisk(self, + mock_get_lv_details, + mock_utils, + mock_proc_mounts, + mock_get_mount_point): + mock_get_lv_details.return_value = {'lv_root': + {'LVM2_LV_NAME': 'lv_root', + 'LVM2_PV_NAME': '/dev/vda2', + 'LVM2_VG_NAME': 'vg_shubhnd'}, + 'lv_swap': + {'LVM2_LV_NAME': 'lv_swap', + 'LVM2_PV_NAME': '/dev/vda2', + 'LVM2_VG_NAME': 'vg_shubhnd'}} + tmp_out = ['', + '', + ' 0', + ' 0', + ' ', + ' ', + ' ', + ' ', + ' vol1', + ' 9510c150-f471-450c-9c6e-1c489792bfb2', + ' 1', + ' Started', + ' 1', + ' 1', + ' 1', + ' 1', + ' 0', + ' Distribute', + ' 0', + ' ', + ' server-1:/tmp/vol1-a', + ' ', + ' 0', + ' ', + ' ', + ' 1', + ' ', + ' ', + ''] + mock_utils.execCmd.return_value = (0, tmp_out, "") + mock_proc_mounts.return_value = {'devpts': '/dev/pts', + '/dev/mapper/vg_shubhnd-lv_root': '/', + 'sysfs': '/sys', + '/proc/bus/usb': '/proc/bus/usb', + 'proc': '/proc'} + mock_get_mount_point.return_value = "/" + bricks = glusternagios.storage.getBricksForDisk("/dev/vda2") + self.assertEquals(bricks, ['server-1:/tmp/vol1-a']) + + @mock.patch('glusternagios.storage._getLvDetails') + @mock.patch('glusternagios.storage.glustercli.utils') + @mock.patch('glusternagios.storage._getMountPoint') + def testGetDisksForBrick(self, + mock_get_mount_point, + mock_utils, + mock_get_lv_details): + mock_get_mount_point.return_value = "/" + tmp_out = ['', + '', + ' 0', + ' 0', + ' (null)', + ' ', + ' ', + ' ', + ' vol1', + ' 1', + ' ', + ' server-1', + ' /tmp/vol1-a', + ' 1', + ' 49152', + ' 8716', + ' 48228589568', + ' 45994987520', + ' /dev/mapper/vg_shubhnd-lv_root', + ' 4096', + ' rw', + ' ext4', + ' ', + ' ', + ' ', + ' ', + ''] + mock_utils.execCmd.return_value = (0, tmp_out, "") + mock_get_lv_details.return_value = {'lv_root': + {'LVM2_LV_NAME': 'lv_root', + 'LVM2_PV_NAME': '/dev/vda2', + 'LVM2_VG_NAME': 'vg_shubhnd'}, + 'lv_swap': + {'LVM2_LV_NAME': 'lv_swap', + 'LVM2_PV_NAME': '/dev/vda2', + 'LVM2_VG_NAME': 'vg_shubhnd'}} + disk = glusternagios.storage.getDisksForBrick("server-1:" + "/tmp/vol1-a") + self.assertEquals(disk, "/dev/vda2") + + disk = glusternagios.storage.getDisksForBrick( + "server-1:/tmp/vol1-a", + "/dev/mapper/vg_shubhnd-lv_root") + self.assertEquals(disk, "/dev/vda2") -- cgit