summaryrefslogtreecommitdiffstats
path: root/glusternagios
diff options
context:
space:
mode:
Diffstat (limited to 'glusternagios')
-rw-r--r--glusternagios/Makefile.am1
-rwxr-xr-xglusternagios/storage.py253
-rw-r--r--glusternagios/utils.py11
3 files changed, 254 insertions, 11 deletions
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