summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSahina Bose <sabose@redhat.com>2014-04-21 13:57:07 +0530
committerBala.FA <barumuga@redhat.com>2014-04-28 16:20:46 +0530
commitb0688de9a2c282763275a47d85fc17b31b5c9848 (patch)
tree4f6e9a945889dd0530eac788ca4f5d2f11e075d5
parenta8a9f59b7c45f1ddc6692ac94ed13ec303484366 (diff)
glustercli: Added method for split-brain status
Added method to check "volume heal <vol-name> info" Change-Id: I367eee5c63e3256f8834ea3845ed7ada6b073001 Signed-off-by: Sahina Bose <sabose@redhat.com>
-rwxr-xr-xglusternagios/glustercli.py50
-rw-r--r--tests/test_glustercli.py50
2 files changed, 100 insertions, 0 deletions
diff --git a/glusternagios/glustercli.py b/glusternagios/glustercli.py
index ff4781b..771feeb 100755
--- a/glusternagios/glustercli.py
+++ b/glusternagios/glustercli.py
@@ -88,6 +88,12 @@ class VolumeQuotaStatus:
EXCEEDED = 'EXCEEDED'
+class VolumeSplitBrainStatus:
+ NOTAPPLICABLE = 'NA'
+ OK = 'OK'
+ SPLITBRAIN = 'SPLITBRAIN'
+
+
class TransportType:
TCP = 'TCP'
RDMA = 'RDMA'
@@ -447,6 +453,50 @@ def _parseVolumeQuotaStatus(out):
return VolumeQuotaStatus.OK
+def _parseVolumeSelfHealSplitBrainInfo(out):
+ value = {}
+ splitbrainentries = 0
+ for line in out:
+ if line.startswith('Number of entries:'):
+ entries = int(line.split(':')[1])
+ if entries > 0:
+ splitbrainentries += entries
+ if splitbrainentries > 0:
+ value['status'] = VolumeSplitBrainStatus.SPLITBRAIN
+ else:
+ value['status'] = VolumeSplitBrainStatus.OK
+ value['unsyncedentries'] = splitbrainentries
+ return value
+
+
+def volumeHealSplitBrainStatus(volumeName, remoteServer=None):
+ """
+ Arguments:
+ * VolumeName
+ Returns:
+ {VOLUMENAME: {'status': SELFHEALSTATUS,
+ 'unsyncedentries': ENTRYCOUNT}}
+ """
+ command = _getGlusterVolCmd() + ["heal", volumeName, "info"]
+ if remoteServer:
+ command += ['--remote-host=%s' % remoteServer]
+
+ rc, out, err = _execGluster(command)
+ volume = {}
+ value = {}
+ if rc == 0:
+ value = _parseVolumeSelfHealSplitBrainInfo(out)
+ volume[volumeName] = value
+ return volume
+ else:
+ if len(err) > 0 and err[0].find("is not of type replicate") > -1:
+ value['status'] = VolumeSplitBrainStatus.NOTAPPLICABLE
+ value['unsyncedentries'] = 0
+ volume[volumeName] = value
+ return volume
+ raise GlusterCmdFailedException(rc=rc, err=err)
+
+
def volumeQuotaStatus(volumeName, remoteServer=None):
"""
Returns:
diff --git a/tests/test_glustercli.py b/tests/test_glustercli.py
index 526aa6e..1d7d517 100644
--- a/tests/test_glustercli.py
+++ b/tests/test_glustercli.py
@@ -1096,6 +1096,35 @@ class GlusterCliTests(TestCaseBase):
except gcli.GlusterCmdFailedException:
assert True
+ @mock.patch('glusternagios.utils.execCmd')
+ @mock.patch('glusternagios.glustercli._getGlusterVolCmd')
+ def test_getVolumeHealSplitBrainStatusNonRepl(self, mock_glusterVolCmd,
+ mock_execCmd,):
+ mock_glusterVolCmd.return_value = ["gluster", "volume"]
+ mock_execCmd.return_value = 2, None, ["Volume test-vol is not "
+ "of type replicate"]
+ expectedOut = {'test-vol':
+ {'status': gcli.VolumeSplitBrainStatus.NOTAPPLICABLE,
+ 'unsyncedentries': 0}}
+ status = gcli.volumeHealSplitBrainStatus("test-vol")
+ print(status)
+ self.assertEquals(status, expectedOut)
+
+ @mock.patch('glusternagios.utils.execCmd')
+ @mock.patch('glusternagios.glustercli._getGlusterVolCmd')
+ def test_getVolumeHealSplitBrainStatus(self, mock_glusterVolCmd,
+ mock_execCmd,):
+ mock_glusterVolCmd.return_value = ["gluster", "volume"]
+ mock_execCmd.return_value = (0,
+ self.__getGlusterSelfHealInfoResult(),
+ None)
+ expectedOut = {'test-vol':
+ {'status': gcli.VolumeSplitBrainStatus.SPLITBRAIN,
+ 'unsyncedentries': 10}}
+ status = gcli.volumeHealSplitBrainStatus("test-vol")
+ print(status)
+ self.assertEquals(status, expectedOut)
+
def __getQuotaOut(self):
return \
[" Path Hard-limit Soft-limit"
@@ -1106,3 +1135,24 @@ class GlusterCliTests(TestCaseBase):
" 200.0KB 0Bytes No No",
"/test/rewe 200.0KB 80% "
"200.0KB 0Bytes Yes Yes"]
+
+ def __getGlusterSelfHealInfoResult(self):
+ return ["Gathering list of entries to be healed "
+ "on volume rep has been successful",
+ "",
+ "Brick node2:/bricks/b3",
+ "Status: Brick is Not connected",
+ "Number of entries: 0"
+ "",
+ "Brick node1:/bricks/b3",
+ "Number of entries: 10",
+ "/dir.7/file.5",
+ "/dir.8/file.3",
+ "/dir.9/file.5",
+ "/dir.2/file.4",
+ "/dir.9/file.4",
+ "/dir.4/file.1",
+ "/file.4",
+ "/dir.7/file.2",
+ "/dir.10/file.2",
+ "/dir.7/file.4"]