Change in vdsm[master]: WIP: Remove Vdsm's dependency on gluster-server package.
dnarayan at redhat.com
dnarayan at redhat.com
Thu May 28 10:41:37 UTC 2015
Darshan N has uploaded a new change for review.
Change subject: WIP: Remove Vdsm's dependency on gluster-server package.
......................................................................
WIP: Remove Vdsm's dependency on gluster-server package.
In this patch have segregated the glusterVolumeInfo code
such that, vdsm package will not be dependent on vdsm-gluster
in turn gluster-server.
Pending: suitable spec file changes.
Change-Id: I43c8f16e8171693d1bbbff40198c59646022603e
Signed-off-by: Darshan N <dnarayan at redhat.com>
---
M tests/functional/networkTests.py
M tests/gluster_cli_tests.py
M vdsm.spec.in
M vdsm/gluster/cli.py
M vdsm/storage/Makefile.am
A vdsm/storage/glusterUtils.py
M vdsm/storage/glusterVolume.py
M vdsm/supervdsmServer
8 files changed, 157 insertions(+), 84 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/68/41568/1
diff --git a/tests/functional/networkTests.py b/tests/functional/networkTests.py
index 553f479..f70bedc 100644
--- a/tests/functional/networkTests.py
+++ b/tests/functional/networkTests.py
@@ -90,7 +90,7 @@
@RequireDummyMod
def setupModule():
"""Persists network configuration."""
- vdsm = VdsProxy()
+ # vdsm = VdsProxy()
vdsm.save_config()
for _ in range(DUMMY_POOL_SIZE):
dummyPool.add(dummy.create())
@@ -98,7 +98,7 @@
def tearDownModule():
"""Restores the network configuration previous to running tests."""
- vdsm = VdsProxy()
+ # vdsm = VdsProxy()
vdsm.restoreNetConfig()
for nic in dummyPool:
dummy.remove(nic)
diff --git a/tests/gluster_cli_tests.py b/tests/gluster_cli_tests.py
index dfbb79a..5e6636a 100644
--- a/tests/gluster_cli_tests.py
+++ b/tests/gluster_cli_tests.py
@@ -20,6 +20,7 @@
from testlib import VdsmTestCase as TestCaseBase
from gluster import cli as gcli
+from storage import glusterUtils as gu
import xml.etree.cElementTree as etree
from nose.plugins.skip import SkipTest
import glusterTestData
@@ -38,7 +39,7 @@
</cliOutput>
"""
tree = etree.fromstring(out)
- self.assertFalse(gcli._parseVolumeInfo(tree))
+ self.assertFalse(gu.parseVolumeInfo(tree))
def _parseVolumeInfo_test(self):
out = """<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
@@ -123,10 +124,10 @@
'stripeCount': '1',
'disperseCount': '0',
'redundancyCount': '0',
- 'transportType': [gcli.TransportType.TCP],
+ 'transportType': [gu.TransportType.TCP],
'uuid': 'b3114c71-741b-4c6f-a39e-80384c4ea3cf',
'volumeName': 'music',
- 'volumeStatus': gcli.VolumeStatus.ONLINE,
+ 'volumeStatus': gu.VolumeStatus.ONLINE,
'volumeType': 'REPLICATE'},
'test1': {'brickCount': '1',
'bricks': ['192.168.122.2:/tmp/t_b1'],
@@ -140,12 +141,12 @@
'stripeCount': '1',
'disperseCount': '0',
'redundancyCount': '0',
- 'transportType': [gcli.TransportType.RDMA],
+ 'transportType': [gu.TransportType.RDMA],
'uuid': 'b444ed94-f346-4cda-bd55-0282f21d22db',
'volumeName': 'test1',
- 'volumeStatus': gcli.VolumeStatus.OFFLINE,
+ 'volumeStatus': gu.VolumeStatus.OFFLINE,
'volumeType': 'DISTRIBUTE'}}
- volumeInfo = gcli._parseVolumeInfo(tree)
+ volumeInfo = gu.parseVolumeInfo(tree)
self.assertEquals(volumeInfo, oVolumeInfo)
def test_parseVolumeInfo(self):
diff --git a/vdsm.spec.in b/vdsm.spec.in
index 5937398..5c99188 100644
--- a/vdsm.spec.in
+++ b/vdsm.spec.in
@@ -1153,6 +1153,7 @@
%{_datadir}/%{vdsm_name}/storage/fileVolume.py*
%{_datadir}/%{vdsm_name}/storage/fuser.py*
%{_datadir}/%{vdsm_name}/storage/glusterSD.py*
+%{_datadir}/%{vdsm_name}/storage/glusterUtils.py*
%{_datadir}/%{vdsm_name}/storage/glusterVolume.py*
%{_datadir}/%{vdsm_name}/storage/hba.py*
%{_datadir}/%{vdsm_name}/storage/hsm.py*
diff --git a/vdsm/gluster/cli.py b/vdsm/gluster/cli.py
index d53a1c8..0d3f041 100644
--- a/vdsm/gluster/cli.py
+++ b/vdsm/gluster/cli.py
@@ -27,6 +27,7 @@
import exception as ge
from hostname import getHostNameFqdn, HostNameException
from . import makePublic
+from storage import glusterUtils as gu
_glusterCommandPath = utils.CommandPath("gluster",
"/usr/sbin/gluster",
@@ -41,15 +42,15 @@
def _getGlusterVolCmd():
- return [_glusterCommandPath.cmd, "--mode=script", "volume"]
+ return [gu.glusterCommandPath.cmd, "--mode=script", "volume"]
def _getGlusterPeerCmd():
- return [_glusterCommandPath.cmd, "--mode=script", "peer"]
+ return [gu.glusterCommandPath.cmd, "--mode=script", "peer"]
def _getGlusterSystemCmd():
- return [_glusterCommandPath.cmd, "system::"]
+ return [gu.glusterCommandPath.cmd, "system::"]
def _getGlusterVolGeoRepCmd():
@@ -57,7 +58,7 @@
def _getGlusterSnapshotCmd():
- return [_glusterCommandPath.cmd, "--mode=script", "snapshot"]
+ return [gu.glusterCommandPath.cmd, "--mode=script", "snapshot"]
class BrickStatus:
@@ -72,16 +73,6 @@
CONNECTED = 'CONNECTED'
DISCONNECTED = 'DISCONNECTED'
UNKNOWN = 'UNKNOWN'
-
-
-class VolumeStatus:
- ONLINE = 'ONLINE'
- OFFLINE = 'OFFLINE'
-
-
-class TransportType:
- TCP = 'TCP'
- RDMA = 'RDMA'
class TaskType:
@@ -357,64 +348,6 @@
raise ge.GlusterXmlErrorException(err=[etree.tostring(xmltree)])
-def _parseVolumeInfo(tree):
- """
- {VOLUMENAME: {'brickCount': BRICKCOUNT,
- 'bricks': [BRICK1, BRICK2, ...],
- 'options': {OPTION: VALUE, ...},
- 'transportType': [TCP,RDMA, ...],
- 'uuid': UUID,
- 'volumeName': NAME,
- 'volumeStatus': STATUS,
- 'volumeType': TYPE,
- 'disperseCount': DISPERSE_COUNT,
- 'redundancyCount': REDUNDANCY_COUNT}, ...}
- """
- volumes = {}
- for el in tree.findall('volInfo/volumes/volume'):
- value = {}
- value['volumeName'] = el.find('name').text
- value['uuid'] = el.find('id').text
- value['volumeType'] = el.find('typeStr').text.upper().replace('-', '_')
- status = el.find('statusStr').text.upper()
- if status == 'STARTED':
- value["volumeStatus"] = VolumeStatus.ONLINE
- else:
- value["volumeStatus"] = VolumeStatus.OFFLINE
- value['brickCount'] = el.find('brickCount').text
- value['distCount'] = el.find('distCount').text
- value['stripeCount'] = el.find('stripeCount').text
- value['replicaCount'] = el.find('replicaCount').text
- value['disperseCount'] = el.find('disperseCount').text
- value['redundancyCount'] = el.find('redundancyCount').text
- transportType = el.find('transport').text
- if transportType == '0':
- value['transportType'] = [TransportType.TCP]
- elif transportType == '1':
- value['transportType'] = [TransportType.RDMA]
- else:
- value['transportType'] = [TransportType.TCP, TransportType.RDMA]
- value['bricks'] = []
- value['options'] = {}
- value['bricksInfo'] = []
- for b in el.findall('bricks/brick'):
- value['bricks'].append(b.text)
- for o in el.findall('options/option'):
- value['options'][o.find('name').text] = o.find('value').text
- for d in el.findall('bricks/brick'):
- brickDetail = {}
- # this try block is to maintain backward compatibility
- # it returns an empty list when gluster doesnot return uuid
- try:
- brickDetail['name'] = d.find('name').text
- brickDetail['hostUuid'] = d.find('hostUuid').text
- value['bricksInfo'].append(brickDetail)
- except AttributeError:
- break
- volumes[value['volumeName']] = value
- return volumes
-
-
def _parseVolumeProfileInfo(tree, nfs):
bricks = []
if nfs:
@@ -493,7 +426,7 @@
except ge.GlusterCmdFailedException as e:
raise ge.GlusterVolumesListFailedException(rc=e.rc, err=e.err)
try:
- return _parseVolumeInfo(xmltree)
+ return gu.parseVolumeInfo(xmltree)
except _etreeExceptions:
raise ge.GlusterXmlErrorException(err=[etree.tostring(xmltree)])
diff --git a/vdsm/storage/Makefile.am b/vdsm/storage/Makefile.am
index 4ebe0a2..fb32d83 100644
--- a/vdsm/storage/Makefile.am
+++ b/vdsm/storage/Makefile.am
@@ -36,6 +36,7 @@
fileVolume.py \
fuser.py \
glusterSD.py \
+ glusterUtils.py \
glusterVolume.py \
hba.py \
hsm.py \
diff --git a/vdsm/storage/glusterUtils.py b/vdsm/storage/glusterUtils.py
new file mode 100644
index 0000000..bde3722
--- /dev/null
+++ b/vdsm/storage/glusterUtils.py
@@ -0,0 +1,132 @@
+import xml.etree.cElementTree as etree
+
+from vdsm import utils
+from vdsm.exception import VdsmException
+
+
+glusterCommandPath = utils.CommandPath("gluster",
+ "/usr/sbin/gluster",)
+
+if hasattr(etree, 'ParseError'):
+ _etreeExceptions = (etree.ParseError, AttributeError, ValueError)
+else:
+ _etreeExceptions = (SyntaxError, AttributeError, ValueError)
+
+
+class VolumeStatus:
+ ONLINE = 'ONLINE'
+ OFFLINE = 'OFFLINE'
+
+
+class TransportType:
+ TCP = 'TCP'
+ RDMA = 'RDMA'
+
+
+class GlusterVolumeInfoFailedException(VdsmException):
+ message = "Gluster volume info command 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
+
+
+def parseVolumeInfo(tree):
+ """
+ {VOLUMENAME: {'brickCount': BRICKCOUNT,
+ 'bricks': [BRICK1, BRICK2, ...],
+ 'options': {OPTION: VALUE, ...},
+ 'transportType': [TCP,RDMA, ...],
+ 'uuid': UUID,
+ 'volumeName': NAME,
+ 'volumeStatus': STATUS,
+ 'volumeType': TYPE,
+ 'disperseCount': DISPERSE_COUNT,
+ 'redundancyCount': REDUNDANCY_COUNT}, ...}
+ """
+ volumes = {}
+ for el in tree.findall('volInfo/volumes/volume'):
+ value = {}
+ value['volumeName'] = el.find('name').text
+ value['uuid'] = el.find('id').text
+ value['volumeType'] = el.find('typeStr').text.upper().replace('-', '_')
+ status = el.find('statusStr').text.upper()
+ if status == 'STARTED':
+ value["volumeStatus"] = VolumeStatus.ONLINE
+ else:
+ value["volumeStatus"] = VolumeStatus.OFFLINE
+ value['brickCount'] = el.find('brickCount').text
+ value['distCount'] = el.find('distCount').text
+ value['stripeCount'] = el.find('stripeCount').text
+ value['replicaCount'] = el.find('replicaCount').text
+ value['disperseCount'] = el.find('disperseCount').text
+ value['redundancyCount'] = el.find('redundancyCount').text
+ transportType = el.find('transport').text
+ if transportType == '0':
+ value['transportType'] = [TransportType.TCP]
+ elif transportType == '1':
+ value['transportType'] = [TransportType.RDMA]
+ else:
+ value['transportType'] = [TransportType.TCP, TransportType.RDMA]
+ value['bricks'] = []
+ value['options'] = {}
+ value['bricksInfo'] = []
+ for b in el.findall('bricks/brick'):
+ value['bricks'].append(b.text)
+ for o in el.findall('options/option'):
+ value['options'][o.find('name').text] = o.find('value').text
+ for d in el.findall('bricks/brick'):
+ brickDetail = {}
+ # this try block is to maintain backward compatibility
+ # it returns an empty list when gluster doesnot return uuid
+ try:
+ brickDetail['name'] = d.find('name').text
+ brickDetail['hostUuid'] = d.find('hostUuid').text
+ value['bricksInfo'].append(brickDetail)
+ except AttributeError:
+ break
+ volumes[value['volumeName']] = value
+ return volumes
+
+
+def volumeInfo(remoteServer, volumeName=None):
+ command = [glusterCommandPath.cmd, "--mode=script", "volume",
+ "info"] + ['--remote-host=%s' % remoteServer]
+ if volumeName:
+ command.append(volumeName)
+ command.append("--xml")
+ rc, out, err = utils.execCmd(command)
+ if rc != 0:
+ raise GlusterVolumeInfoFailedException(rc, out, err)
+ try:
+ tree = etree.fromstring('\n'.join(out))
+ rv = int(tree.find('opRet').text)
+ msg = tree.find('opErrstr').text
+ errNo = int(tree.find('opErrno').text)
+ except _etreeExceptions:
+ raise GlusterVolumeInfoFailedException(err=out)
+ if rv != 0:
+ if errNo != 0:
+ rv = errNo
+ raise GlusterVolumeInfoFailedException(rc=rv, err=[msg])
+ try:
+ return parseVolumeInfo(tree)
+ except _etreeExceptions:
+ raise GlusterVolumeInfoFailedException(err=[etree.tostring(tree)])
diff --git a/vdsm/storage/glusterVolume.py b/vdsm/storage/glusterVolume.py
index 647b1ec..910b22f 100644
--- a/vdsm/storage/glusterVolume.py
+++ b/vdsm/storage/glusterVolume.py
@@ -3,7 +3,7 @@
from sdc import sdCache
import supervdsm as svdsm
try:
- from gluster.exception import GlusterException
+ from glusterUtils import GlusterVolumeInfoFailedException
_glusterEnabled = True
except ImportError:
_glusterEnabled = False
@@ -31,9 +31,9 @@
svdsmProxy = svdsm.getProxy()
try:
- volInfo = svdsmProxy.glusterVolumeInfo(volname, volfileServer)
+ volInfo = svdsmProxy.volumeInfo(volname, volfileServer)
volTrans = VOLUME_TRANS_MAP[volInfo[volname]['transportType'][0]]
- except GlusterException:
+ except GlusterVolumeInfoFailedException:
# In case of issues with finding transport type, default to tcp
self.log.warning("Unable to find transport type for GlusterFS"
" volume %s. GlusterFS server = %s."
diff --git a/vdsm/supervdsmServer b/vdsm/supervdsmServer
index ef7a710..53e80f2 100755
--- a/vdsm/supervdsmServer
+++ b/vdsm/supervdsmServer
@@ -68,6 +68,7 @@
from storage.iscsi import readSessionInfo as _readSessionInfo
from supervdsm import _SuperVdsmManager
from storage import hba
+from storage import glusterUtils
from storage.fileUtils import chown, resolveGid, resolveUid
from storage.fileUtils import validateAccess as _validateAccess
from vdsm.constants import METADATA_GROUP, EXT_CHOWN, EXT_UDEVADM, \
@@ -419,6 +420,10 @@
sysctl.set_rp_filter_loose(dev)
@logDecorator
+ def volumeInfo(self, remoteServer, volumeName=None):
+ return glusterUtils.volumeInfo(remoteServer, volumeName)
+
+ @logDecorator
def set_rp_filter_strict(self, dev):
sysctl.set_rp_filter_strict(dev)
--
To view, visit https://gerrit.ovirt.org/41568
To unsubscribe, visit https://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I43c8f16e8171693d1bbbff40198c59646022603e
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Darshan N <dnarayan at redhat.com>
More information about the vdsm-patches
mailing list