Change in vdsm[master]: gluster: command to create a public key file
by dnarayan@redhat.com
Hello Bala.FA,
I'd like you to do a code review. Please visit
http://gerrit.ovirt.org/17644
to review the following change.
Change subject: gluster: command to create a public key file
......................................................................
gluster: command to create a public key file
This executes the command to create a public key file
which will have public keys of all the hosts of source cluster.
This is needed for password-less communication between
slave cluster hosts during geo-replication
Change-Id: If8c979a89ce11a1622819c474b59dcf088733594
Signed-off-by: ndarshan <dnarayan(a)redhat.com>
---
M vdsm/gluster/cli.py
M vdsm/gluster/exception.py
2 files changed, 20 insertions(+), 0 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/44/17644/1
diff --git a/vdsm/gluster/cli.py b/vdsm/gluster/cli.py
index bac6d1c..64529ae 100644
--- a/vdsm/gluster/cli.py
+++ b/vdsm/gluster/cli.py
@@ -897,3 +897,12 @@
return _parseVolumeProfileInfo(xmltree, nfs)
except _etreeExceptions:
raise ge.GlusterXmlErrorException(err=[etree.tostring(xmltree)])
+
+@makePublic
+def createPublicKeyFile():
+ command = _getGlusterSystemCmd() + ["execute", "gsec_create"]
+ rc, out, err = _execGluster(command)
+ if rc:
+ raise ge.GlusterGeoRepPublicKeyFileCreationFailedException(rc, out, err)
+ else:
+ return True
diff --git a/vdsm/gluster/exception.py b/vdsm/gluster/exception.py
index c569a9e..1ee73bb 100644
--- a/vdsm/gluster/exception.py
+++ b/vdsm/gluster/exception.py
@@ -484,3 +484,14 @@
prefix = "%s: " % (action)
self.message = prefix + "Service action is not supported"
self.err = [self.message]
+
+#geo-replication
+class GlusterGeoRepException(GlusterException):
+ code = 4560
+ message = "Gluster Geo-Replication Exception"
+
+
+class GlusterGeoRepPublicKeyFileCreationFailedException(GlusterGeoRepException):
+ code = 4561
+ message = "Creation of public key file failed"
+
--
To view, visit http://gerrit.ovirt.org/17644
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: If8c979a89ce11a1622819c474b59dcf088733594
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: ndarshan <dnarayan(a)redhat.com>
Gerrit-Reviewer: Bala.FA <barumuga(a)redhat.com>
9 years, 1 month
Change in vdsm[master]: vdsm-gluster: Added gluster volume geo-replication start verb
by tjeyasin@redhat.com
Hello Ayal Baron, Bala.FA, Saggi Mizrahi, Dan Kenigsberg,
I'd like you to do a code review. Please visit
http://gerrit.ovirt.org/17766
to review the following change.
Change subject: vdsm-gluster: Added gluster volume geo-replication start verb
......................................................................
vdsm-gluster: Added gluster volume geo-replication start verb
Start the geo-replication session between the hosts.
Start distributed geo-replication on all the nodes that are a part
of the master-volume. Even if any node, that is a part of the
master-volume is down, the command will still be successful.
Change-Id: I3cf03c748cf9fe28efe7d407727cd52da20701c5
Signed-off-by: Timothy Asir <tjeyasin(a)redhat.com>
---
M client/vdsClientGluster.py
M vdsm/gluster/api.py
M vdsm/gluster/cli.py
M vdsm/gluster/exception.py
4 files changed, 100 insertions(+), 0 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/66/17766/1
diff --git a/client/vdsClientGluster.py b/client/vdsClientGluster.py
index 90af83e..feb6387 100644
--- a/client/vdsClientGluster.py
+++ b/client/vdsClientGluster.py
@@ -424,6 +424,34 @@
pp.pprint(status)
return status['status']['code'], status['status']['message']
+ def do_glusterVolumeGeoRepStart(self, args):
+ params = self._eqSplit(args)
+ masterVolName = params.get('masterVolName', '')
+ slaveHost = params.get('slaveHost', '')
+ slaveVolName = params.get('slaveVolName', '')
+ if not(masterVolName and slaveHost and slaveVolName):
+ raise ValueError
+
+ status = self.s.glusterVolumeGeoRepStart(masterVolName,
+ slaveHost,
+ slaveVolName)
+ pp.pprint(status)
+ return status['status']['code'], status['status']['message']
+
+ def do_glusterVolumeGeoRepStop(self, args):
+ params = self._eqSplit(args)
+ masterVolName = params.get('masterVolName', '')
+ slaveHost = params.get('slaveHost', '')
+ slaveVolName = params.get('slaveVolName', '')
+ if not(masterVolName and slaveHost and slaveVolName):
+ raise ValueError
+
+ status = self.s.glusterVolumeGeoRepStop(masterVolName,
+ slaveHost,
+ slaveVolName)
+ pp.pprint(status)
+ return status['status']['code'], status['status']['message']
+
def getGlusterCmdDict(serv):
return \
@@ -705,4 +733,26 @@
'not set'
'(swift, glusterd, smb, memcached)'
)),
+ 'glusterVolumeGeoRepStart': (
+ serv.do_glusterVolumeGeoRepStart,
+ ('masterVolName=<master_volume_name> slaveHost=<slave_host> '
+ 'slaveVolName=<slave_volume_name>\n\t'
+ '<master_volume_name> is an existing volume name in the '
+ 'master node\n\t'
+ '<slave_host> is slave host name\n\t'
+ '<slave_volume_name> is an existing volume name in the '
+ 'slave node',
+ 'start volume geo-replication'
+ )),
+ 'glusterVolumeGeoRepStop': (
+ serv.do_glusterVolumeGeoRepStop,
+ ('masterVolName=<master_volume_name> slaveHost=<slave_host> '
+ 'slaveVolName=<slave_volume_name>\n\t'
+ '<master_volume_name> is an existing volume name in the '
+ 'master node\n\t'
+ '<slave_host> is slave host name\n\t'
+ '<slave_volume_name> is an existing volume name in the '
+ 'slave node',
+ 'stop volume geo-replication'
+ )),
}
diff --git a/vdsm/gluster/api.py b/vdsm/gluster/api.py
index 4bd8308..ed9f5ae 100644
--- a/vdsm/gluster/api.py
+++ b/vdsm/gluster/api.py
@@ -287,6 +287,20 @@
status = self.svdsmProxy.glusterServicesGet(serviceNames)
return {'services': status}
+ @exportAsVerb
+ def volumeGeoRepStart(self, masterVolName, slaveHost, slaveVolName,
+ options=None):
+ self.svdsmProxy.glusterVolumeGeoRepStart(masterVolName,
+ slaveHost,
+ slaveVolName)
+
+ @exportAsVerb
+ def volumeGeoRepStop(self, masterVolName, slaveHost, slaveVolName,
+ options=None):
+ self.svdsmProxy.glusterVolumeGeoRepStop(masterVolName,
+ slaveHost,
+ slaveVolName)
+
def getGlusterMethods(gluster):
l = []
diff --git a/vdsm/gluster/cli.py b/vdsm/gluster/cli.py
index bac6d1c..e4d6615 100644
--- a/vdsm/gluster/cli.py
+++ b/vdsm/gluster/cli.py
@@ -897,3 +897,29 @@
return _parseVolumeProfileInfo(xmltree, nfs)
except _etreeExceptions:
raise ge.GlusterXmlErrorException(err=[etree.tostring(xmltree)])
+
+
+@makePublic
+def volumeGeoRepStart(masterVolName, slaveHost, slaveVolName):
+ command = _getGlusterVolCmd() + ["geo-replication", masterVolName,
+ "%s::%s" % (slaveHost, slaveVolName),
+ "start"]
+ try:
+ _execGlusterXml(command)
+ return True
+ except ge.GlusterCmdFailedException as e:
+ raise ge.GlusterVolumeGeoRepStartFailedException(rc=e.rc,
+ err=e.err)
+
+
+@makePublic
+def volumeGeoRepStop(masterVolName, slaveHost, slaveVolName):
+ command = _getGlusterVolCmd() + ["geo-replication", masterVolName,
+ "%s::%s" % (slaveHost, slaveVolName),
+ "stop"]
+ try:
+ _execGlusterXml(command)
+ return True
+ except ge.GlusterCmdFailedException as e:
+ raise ge.GlusterVolumeGeoRepStopFailedException(rc=e.rc,
+ err=e.err)
diff --git a/vdsm/gluster/exception.py b/vdsm/gluster/exception.py
index c569a9e..259df32 100644
--- a/vdsm/gluster/exception.py
+++ b/vdsm/gluster/exception.py
@@ -484,3 +484,13 @@
prefix = "%s: " % (action)
self.message = prefix + "Service action is not supported"
self.err = [self.message]
+
+
+class GlusterVolumeGeoRepStartFailedException(GlusterVolumeException):
+ code = 4164
+ message = "Volume geo-replication start failed"
+
+
+class GlusterVolumeGeoRepStopFailedException(GlusterVolumeException):
+ code = 4165
+ message = "Volume geo-replication stop failed"
--
To view, visit http://gerrit.ovirt.org/17766
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I3cf03c748cf9fe28efe7d407727cd52da20701c5
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Timothy Asir <tjeyasin(a)redhat.com>
Gerrit-Reviewer: Ayal Baron <abaron(a)redhat.com>
Gerrit-Reviewer: Bala.FA <barumuga(a)redhat.com>
Gerrit-Reviewer: Dan Kenigsberg <danken(a)redhat.com>
Gerrit-Reviewer: Saggi Mizrahi <smizrahi(a)redhat.com>
9 years, 3 months
Change in vdsm[master]: gluster: geo replication status and status detail
by dnarayan@redhat.com
Hello Bala.FA,
I'd like you to do a code review. Please visit
http://gerrit.ovirt.org/18414
to review the following change.
Change subject: gluster: geo replication status and status detail
......................................................................
gluster: geo replication status and status detail
this has two verbs, status: provides geo-replication status of all running
sessions or all sessions associated with a perticular source volume or
session between a source and remote volume. status detail: provides detailed
status of geo-repliction session between source and remote volume
Change-Id: I4f37f35a5480fbe049a67758e122d4a0c2eba513
Signed-off-by: ndarshan <dnarayan(a)redhat.com>
---
M client/vdsClientGluster.py
M vdsm/gluster/api.py
M vdsm/gluster/cli.py
M vdsm/gluster/exception.py
M vdsm/gluster/vdsmapi-gluster-schema.json
5 files changed, 223 insertions(+), 0 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/14/18414/1
diff --git a/client/vdsClientGluster.py b/client/vdsClientGluster.py
index 90af83e..76a5ba8 100644
--- a/client/vdsClientGluster.py
+++ b/client/vdsClientGluster.py
@@ -424,6 +424,35 @@
pp.pprint(status)
return status['status']['code'], status['status']['message']
+ def do_glusterVolumeGeoRepStatus(self, args):
+ params = self._eqSplit(args)
+ try:
+ volName = params.get('volName', '')
+ remoteHost = params.get('remoteHost', '')
+ remoteVolName = params.get('remoteVolName', '')
+ except:
+ raise ValueError
+ status = self.s.glusterVolumeGeoRepStatus(volName, remoteHost,
+ remoteVolName)
+ pp.pprint(status)
+ return status['status']['code'], status['status']['message']
+
+ def do_glusterVolumeGeoRepStatusDetail(self, args):
+ params = self._eqSplit(args)
+ try:
+ volName = params.get('volName', '')
+ remoteHost = params.get('remoteHost', '')
+ remoteVolName = params.get('remoteVolName', '')
+ except:
+ raise ValueError
+ if not (volName and remoteHost and remoteVolName):
+ raise ValueError
+ status = self.s.glusterVolumeGeoRepStatusDetail(volName,
+ remoteHost,
+ remoteVolName)
+ pp.pprint(status)
+ return status['status']['code'], status['status']['message']
+
def getGlusterCmdDict(serv):
return \
@@ -705,4 +734,24 @@
'not set'
'(swift, glusterd, smb, memcached)'
)),
+ 'glusterVolumeGeoRepStatus': (
+ serv.do_glusterVolumeGeoRepStatus,
+ ('volName=<master_volume_name> '
+ 'remoteHost=<slave_host_name> '
+ 'remoteVolName=<slave_volume_name> '
+ '<master_volume_name>existing volume name in the master node\n\t'
+ '<slave_host_name>is remote slave host name or ip\n\t'
+ '<slave_volume_name>existing volume name in the slave node',
+ 'Returns ths status of geo-replication'
+ )),
+ 'glusterVolumeGeoRepStatusDetail': (
+ serv.do_glusterVolumeGeoRepStatusDetail,
+ ('volName=<master_volume_name> '
+ 'remoteHost=<slave_host_name> '
+ 'remoteVolName=<slave_volume_name> '
+ '<master_volume_name>existing volume name in the master node\n\t'
+ '<slave_host_name>is remote slave host name or ip\n\t'
+ '<slave_volume_name>existing volume name in the slave node',
+ 'Returns the Detailed status of geo-replication'
+ ))
}
diff --git a/vdsm/gluster/api.py b/vdsm/gluster/api.py
index 4bd8308..d24e700 100644
--- a/vdsm/gluster/api.py
+++ b/vdsm/gluster/api.py
@@ -287,6 +287,22 @@
status = self.svdsmProxy.glusterServicesGet(serviceNames)
return {'services': status}
+ @exportAsVerb
+ def volumeGeoRepStatus(self, volName=None, remoteHost=None,
+ remoteVolName=None, options=None):
+ status = self.svdsmProxy.glusterVolumeGeoRepStatus(volName,
+ remoteHost,
+ remoteVolName)
+ return {'geo-rep': status}
+
+ @exportAsVerb
+ def volumeGeoRepStatusDetail(self, volName, remoteHost,
+ remoteVolName, options=None):
+ status = self.svdsmProxy.glusterVolumeGeoRepStatusDetail(volName,
+ remoteHost,
+ remoteVolName)
+ return {'geo-rep': status}
+
def getGlusterMethods(gluster):
l = []
diff --git a/vdsm/gluster/cli.py b/vdsm/gluster/cli.py
index bac6d1c..1cf0e12 100644
--- a/vdsm/gluster/cli.py
+++ b/vdsm/gluster/cli.py
@@ -897,3 +897,59 @@
return _parseVolumeProfileInfo(xmltree, nfs)
except _etreeExceptions:
raise ge.GlusterXmlErrorException(err=[etree.tostring(xmltree)])
+
+
+def _parseGeoRepStatusDetail(tree):
+ status = {'node': tree.find('geoRep/node').text,
+ 'health': tree.find('geoRep/health').text,
+ 'uptime': tree.find('geoRep/uptime').text,
+ 'filesSyncd': tree.find('geoRep/filesSyncd').text,
+ 'filesPending': tree.find('geoRep/filesPending').text,
+ 'bytesPending': tree.find('geoRep/bytesPending').text,
+ 'deletesPending': tree.find('geoRep/deletesPending').text}
+ return status
+
+
+def _parseGeoRepStatus(tree):
+ pairs = []
+ for el in tree.findall('geoRep/pair'):
+ value = {}
+ value['node'] = el.find('node').text
+ value['master'] = el.find('master').text
+ value['slave'] = el.find('slave').text
+ value['health'] = el.find('health').text
+ value['uptime'] = el.find('uptime').text
+ pairs.append(value)
+ return pairs
+
+
+@makePublic
+def volumeGeoRepStatus(volName=None, remoteHost=None, remoteVolName=None,
+ ):
+ command = _getGlusterVolCmd() + ["geo-replication", volName,
+ "%s::%s" % (remoteHost, remoteVolName),
+ "status"]
+ try:
+ xmltree = _execGlusterXml(command)
+ except ge.GlusterCmdFailedException as e:
+ raise ge.GlusterGeoRepStatusFailedException(rc=e.rc, err=e.err)
+ try:
+ return _parseGeoRepStatus(xmltree)
+ except _etreeExceptions:
+ raise ge.GlusterXmlErrorException(err=[etree.tostring(xmltree)])
+
+
+@makePublic
+def volumeGeoRepStatusDetail(volName, remoteHost, remoteVolName,
+ ):
+ command = _getGlusterVolCmd() + ["geo-replication", volName,
+ "%s::%s" % (remoteHost, remoteVolName),
+ "status", "detail"]
+ try:
+ xmltree = _execGlusterXml(command)
+ except ge.GlusterCmdFailedException as e:
+ raise ge.GlusterGeoRepStatusDetailFailedException(rc=e.rc, err=e.err)
+ try:
+ return _parseGeoRepStatusDetail(xmltree)
+ except _etreeExceptions:
+ raise ge.GlusterXmlErrorException(err=[etree.tostring(xmltree)])
diff --git a/vdsm/gluster/exception.py b/vdsm/gluster/exception.py
index c569a9e..d95b168 100644
--- a/vdsm/gluster/exception.py
+++ b/vdsm/gluster/exception.py
@@ -484,3 +484,19 @@
prefix = "%s: " % (action)
self.message = prefix + "Service action is not supported"
self.err = [self.message]
+
+
+#geo-replication
+class GlusterGeoRepException(GlusterException):
+ code = 4560
+ message = "Gluster Geo-Replication Exception"
+
+
+class GlusterGeoRepStatusFailedException(GlusterGeoRepException):
+ code = 4565
+ message = "Geo Rep status failed"
+
+
+class GlusterGeoRepStatusDetailFailedException(GlusterGeoRepException):
+ code = 4566
+ message = "Geo Rep status detail failed"
diff --git a/vdsm/gluster/vdsmapi-gluster-schema.json b/vdsm/gluster/vdsmapi-gluster-schema.json
index 7a4c034..557c750 100644
--- a/vdsm/gluster/vdsmapi-gluster-schema.json
+++ b/vdsm/gluster/vdsmapi-gluster-schema.json
@@ -372,3 +372,89 @@
{'command': {'class': 'GlusterService', 'name': 'action'},
'data': {'serviceName': 'str', 'action': 'GlusterServiceAction'},
'returns': 'GlusterServicesStatusInfo'}
+
+##
+# @GlusterGeoRepStatus:
+#
+# Gluster geo-replication status information.
+#
+# @node: The node where geo-replication is started
+#
+# @master: The source for geo-replication
+#
+# @slave: The destination of geo-replication
+#
+# @health: The status of the geo-replication session
+#
+# @uptime: The time since the geo-replication started
+#
+# Since: 4.10.3
+##
+{'type': 'GlusterGeoRepStatus',
+ 'data': {'node': 'str', 'master': 'str', 'slave': 'str', 'health': 'str', 'uptime': 'int'}}
+
+
+##
+# @GlusterVolume.geoRepStatus:
+#
+# Gets the status of geo-Replication session
+#
+# @masterVolName: Is an existing volume name in the master node
+#
+# @slaveHost: Is remote slave host name or ip
+#
+# @slaveVolName: Is an available existing volume name in the slave node
+#
+# Returns:
+# status information for geo-replication
+#
+# Since: 4.10.3
+##
+{'command': {'class': 'GlusterVolume', 'name': 'geoRepStatus'},
+ 'data': {'masterVolName': 'str', 'slaveHost': 'str', 'slaveVolName': 'str'},
+ 'returns': 'GlusterGeoRepStatus'}
+
+##
+# @GlusterGeoRepStatusDetail:
+#
+# Gluster geo-replication detailed status information.
+#
+# @node: The node where geo-replication is started
+#
+# @health: The status of the geo-replication session
+#
+# @uptime: The time since the geo-replication started
+#
+# @filesSyncd: The number of files that are synced
+#
+# @filesPending: The number of files that are pending to be synced
+#
+# @bytesPending: The number of bytes that are pending to be synced
+#
+# @deletesPending: The number of deletes that are pending
+#
+# Since: 4.10.3
+##
+{'type': 'GlusterGeoRepStatusDetail',
+ 'data': {'node': 'str', 'health': 'str', 'uptime': 'int', 'filesSyncd': 'int', 'filesPending': 'int',
+ 'bytesPending': 'int','deletesPending': 'int'}}
+
+##
+# @GlusterVolume.geoRepStatusDetail:
+#
+# Gets the detailed status of geo-Replication session
+#
+# @masterVolName: Is an existing volume name in the master node
+#
+# @slaveHost: Is remote slave host name or ip
+#
+# @slaveVolName: Is an available existing volume name in the slave node
+#
+# Returns:
+# detailed status information of geo-replication session
+#
+# Since: 4.10.3
+##
+{'command': {'class': 'GlusterVolume', 'name': 'geoRepStatusDetail'},
+ 'data': {'masterVolName': 'str', 'slaveHost': 'str', 'slaveVolName': 'str'},
+ 'returns': 'GlusterGeoRepStatusDetail'}
--
To view, visit http://gerrit.ovirt.org/18414
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I4f37f35a5480fbe049a67758e122d4a0c2eba513
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: ndarshan <dnarayan(a)redhat.com>
Gerrit-Reviewer: Bala.FA <barumuga(a)redhat.com>
9 years, 3 months
Change in vdsm[master]: vdsm: Refactoring of retrieving device info from xml
by Vinzenz Feenstra
Vinzenz Feenstra has uploaded a new change for review.
Change subject: vdsm: Refactoring of retrieving device info from xml
......................................................................
vdsm: Refactoring of retrieving device info from xml
Reworked a bit the retrieval of device info from the libvirt domain xml.
Now VDSM won't parse the code in lastXmlDesc every time and the retrieval
of elements from the domain xml has been a bit abstracted.
Additionally the retrieval of an alias has been moved into a separate
function call to make the readability a bit better.
Change-Id: I7e106b2f2d3f4160d4e882f1a2880cb1b52fbb22
Signed-off-by: Vinzenz Feenstra <vfeenstr(a)redhat.com>
---
M vdsm/vm.py
1 file changed, 63 insertions(+), 76 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/94/17694/1
diff --git a/vdsm/vm.py b/vdsm/vm.py
index dc52909..e51050e 100644
--- a/vdsm/vm.py
+++ b/vdsm/vm.py
@@ -1698,6 +1698,7 @@
self._guestSocketFile = self._makeChannelPath(_VMCHANNEL_DEVICE_NAME)
self._qemuguestSocketFile = self._makeChannelPath(_QEMU_GA_DEVICE_NAME)
self._lastXMLDesc = '<domain><uuid>%s</uuid></domain>' % self.id
+ self._lastParsedXmlDesc = _domParseStr(self._lastXMLDesc)
self._devXmlHash = '0'
self._released = False
self._releaseLock = threading.Lock()
@@ -2722,24 +2723,30 @@
self._guestCpuRunning = (self._dom.info()[0] ==
libvirt.VIR_DOMAIN_RUNNING)
+ def _getDevicesXml(self, parsedXml=None):
+ parsedXml = parsedXml or self._lastParsedXmlDesc
+ return parsedXml.childNodes[0].getElementsByTagName('devices')[0]
+
def _getUnderlyingVmDevicesInfo(self):
"""
Obtain underlying vm's devices info from libvirt.
"""
- self._getUnderlyingNetworkInterfaceInfo()
- self._getUnderlyingDriveInfo()
- self._getUnderlyingDisplayPort()
- self._getUnderlyingSoundDeviceInfo()
- self._getUnderlyingVideoDeviceInfo()
- self._getUnderlyingControllerDeviceInfo()
- self._getUnderlyingBalloonDeviceInfo()
- self._getUnderlyingWatchdogDeviceInfo()
- self._getUnderlyingSmartcardDeviceInfo()
- self._getUnderlyingConsoleDeviceInfo()
+ devicesXml = self._getDevicesXml(parsedXml=self._lastParsedXmlDesc)
+ self._getUnderlyingNetworkInterfaceInfo(devicesXml=devicesXml)
+ self._getUnderlyingDriveInfo(devicesXml=devicesXml)
+ self._getUnderlyingDisplayPort(xml=self._lastParsedXmlDesc)
+ self._getUnderlyingSoundDeviceInfo(devicesXml=devicesXml)
+ self._getUnderlyingVideoDeviceInfo(devicesXml=devicesXml)
+ self._getUnderlyingControllerDeviceInfo(devicesXml=devicesXml)
+ self._getUnderlyingBalloonDeviceInfo(devicesXml=devicesXml)
+ self._getUnderlyingWatchdogDeviceInfo(devicesXml=devicesXml)
+ self._getUnderlyingSmartcardDeviceInfo(devicesXml=devicesXml)
+ self._getUnderlyingConsoleDeviceInfo(devicesXml=devicesXml)
# Obtain info of all unknown devices. Must be last!
- self._getUnderlyingUnknownDeviceInfo()
+ self._getUnderlyingUnknownDeviceInfo(devicesXml=devicesXml)
+ self._updateAgentChannels(devicesXml=devicesXml)
- def _updateAgentChannels(self):
+ def _updateAgentChannels(self, devicesXml):
"""
We moved the naming of guest agent channel sockets. To keep backwards
compatability we need to make symlinks from the old channel sockets, to
@@ -2747,9 +2754,7 @@
This is necessary to prevent incoming migrations, restoring of VMs and
the upgrade of VDSM with running VMs to fail on this.
"""
- agentChannelXml = _domParseStr(self._lastXMLDesc).childNodes[0]. \
- getElementsByTagName('devices')[0]. \
- getElementsByTagName('channel')
+ agentChannelXml = devicesXml.getElementsByTagName('channel')
for channel in agentChannelXml:
try:
name = channel.getElementsByTagName('target')[0].\
@@ -2781,7 +2786,6 @@
self._getUnderlyingVmInfo()
self._getUnderlyingVmDevicesInfo()
- self._updateAgentChannels()
#Currently there is no protection agains mirroring a network twice,
for nic in self._devices[NIC_DEVICES]:
@@ -2937,9 +2941,8 @@
or revert to snapshot.
"""
parsedSrcDomXML = _domParseStr(srcDomXML)
-
- allDiskDeviceXmlElements = parsedSrcDomXML.childNodes[0]. \
- getElementsByTagName('devices')[0].getElementsByTagName('disk')
+ devicesXml = self._getDevicesXml(parsedXml=parsedSrcDomXML)
+ allDiskDeviceXmlElements = devicesXml.getElementsByTagName('disk')
snappableDiskDeviceXmlElements = \
_filterSnappableDiskDevices(allDiskDeviceXmlElements)
@@ -3008,7 +3011,8 @@
with self._confLock:
self.conf['devices'].append(nicParams)
self.saveState()
- self._getUnderlyingNetworkInterfaceInfo()
+ self._getUnderlyingNetworkInterfaceInfo(
+ devicesXml=self._getDevicesXml())
hooks.after_nic_hotplug(nicXml, self.conf,
params=customProps)
@@ -3264,7 +3268,7 @@
with self._confLock:
self.conf['devices'].append(diskParams)
self.saveState()
- self._getUnderlyingDriveInfo()
+ self._getUnderlyingDriveInfo(devicesXml=self._getDevicesXml())
hooks.after_disk_hotplug(driveXml, self.conf,
params=customProps)
@@ -4181,8 +4185,8 @@
def _getUnderlyingVmInfo(self):
self._lastXMLDesc = self._dom.XMLDesc(0)
- devxml = _domParseStr(self._lastXMLDesc).childNodes[0]. \
- getElementsByTagName('devices')[0]
+ self._lastParsedXmlDesc = _domParseStr(self._lastXMLDesc)
+ devxml = self._getDevicesXml()
self._devXmlHash = str(hash(devxml.toxml()))
return self._lastXMLDesc
@@ -4331,6 +4335,9 @@
self.saveState()
return {'status': doneCode}
+ def _getUnderlyingDeviceAliasName(self, devXml):
+ return devXml.getElementsByTagName('alias')[0].getAttribute('name')
+
def _getUnderlyingDeviceAddress(self, devXml):
"""
Obtain device's address from libvirt
@@ -4347,7 +4354,7 @@
return address
- def _getUnderlyingUnknownDeviceInfo(self):
+ def _getUnderlyingUnknownDeviceInfo(self, devicesXml):
"""
Obtain unknown devices info from libvirt.
@@ -4360,16 +4367,13 @@
return True
return False
- devsxml = _domParseStr(self._lastXMLDesc).childNodes[0]. \
- getElementsByTagName('devices')[0]
-
- for x in devsxml.childNodes:
+ for x in devicesXml.childNodes:
# Ignore empty nodes and devices without address
if (x.nodeName == '#text' or
not x.getElementsByTagName('address')):
continue
- alias = x.getElementsByTagName('alias')[0].getAttribute('name')
+ alias = self._getUnderlyingDeviceAliasName(x)
if not isKnownDevice(alias):
address = self._getUnderlyingDeviceAddress(x)
# I general case we assume that device has attribute 'type',
@@ -4381,18 +4385,16 @@
'address': address}
self.conf['devices'].append(newDev)
- def _getUnderlyingControllerDeviceInfo(self):
+ def _getUnderlyingControllerDeviceInfo(self, devicesXml):
"""
Obtain controller devices info from libvirt.
"""
- ctrlsxml = _domParseStr(self._lastXMLDesc).childNodes[0]. \
- getElementsByTagName('devices')[0]. \
- getElementsByTagName('controller')
+ ctrlsxml = devicesXml.getElementsByTagName('controller')
for x in ctrlsxml:
# Ignore controller devices without address
if not x.getElementsByTagName('address'):
continue
- alias = x.getElementsByTagName('alias')[0].getAttribute('name')
+ alias = self._getUnderlyingDeviceAliasName(x)
device = x.getAttribute('type')
# Get model and index. Relevant for USB controllers.
model = x.getAttribute('model')
@@ -4428,20 +4430,18 @@
'address': address,
'alias': alias})
- def _getUnderlyingBalloonDeviceInfo(self):
+ def _getUnderlyingBalloonDeviceInfo(self, devicesXml):
"""
Obtain balloon device info from libvirt.
"""
- balloonxml = _domParseStr(self._lastXMLDesc).childNodes[0]. \
- getElementsByTagName('devices')[0]. \
- getElementsByTagName('memballoon')
+ balloonxml = devicesXml.getElementsByTagName('memballoon')
for x in balloonxml:
# Ignore balloon devices without address.
if not x.getElementsByTagName('address'):
address = None
else:
address = self._getUnderlyingDeviceAddress(x)
- alias = x.getElementsByTagName('alias')[0].getAttribute('name')
+ alias = self._getUnderlyingDeviceAliasName(x)
for dev in self._devices[BALLOON_DEVICES]:
if address and not hasattr(dev, 'address'):
@@ -4456,16 +4456,14 @@
if not dev.get('alias'):
dev['alias'] = alias
- def _getUnderlyingConsoleDeviceInfo(self):
+ def _getUnderlyingConsoleDeviceInfo(self, devicesXml):
"""
Obtain the alias for the console device from libvirt
"""
- consolexml = _domParseStr(self._lastXMLDesc).childNodes[0].\
- getElementsByTagName('devices')[0].\
- getElementsByTagName('console')
+ consolexml = devicesXml.getElementsByTagName('console')
for x in consolexml:
# All we care about is the alias
- alias = x.getElementsByTagName('alias')[0].getAttribute('name')
+ alias = self._getUnderlyingDeviceAliasName(x)
for dev in self._devices[CONSOLE_DEVICES]:
if not hasattr(dev, 'alias'):
dev.alias = alias
@@ -4475,19 +4473,17 @@
not dev.get('alias'):
dev['alias'] = alias
- def _getUnderlyingSmartcardDeviceInfo(self):
+ def _getUnderlyingSmartcardDeviceInfo(self, devicesXml):
"""
Obtain smartcard device info from libvirt.
"""
- smartcardxml = _domParseStr(self._lastXMLDesc).childNodes[0].\
- getElementsByTagName('devices')[0].\
- getElementsByTagName('smartcard')
+ smartcardxml = devicesXml.getElementsByTagName('smartcard')
for x in smartcardxml:
if not x.getElementsByTagName('address'):
continue
address = self._getUnderlyingDeviceAddress(x)
- alias = x.getElementsByTagName('alias')[0].getAttribute('name')
+ alias = self._getUnderlyingDeviceAliasName(x)
for dev in self._devices[SMARTCARD_DEVICES]:
if not hasattr(dev, 'address'):
@@ -4500,19 +4496,17 @@
dev['address'] = address
dev['alias'] = alias
- def _getUnderlyingWatchdogDeviceInfo(self):
+ def _getUnderlyingWatchdogDeviceInfo(self, devicesXml):
"""
Obtain watchdog device info from libvirt.
"""
- watchdogxml = _domParseStr(self._lastXMLDesc).childNodes[0]. \
- getElementsByTagName('devices')[0]. \
- getElementsByTagName('watchdog')
+ watchdogxml = devicesXml.getElementsByTagName('watchdog')
for x in watchdogxml:
# PCI watchdog has "address" different from ISA watchdog
if x.getElementsByTagName('address'):
address = self._getUnderlyingDeviceAddress(x)
- alias = x.getElementsByTagName('alias')[0].getAttribute('name')
+ alias = self._getUnderlyingDeviceAliasName(x)
for wd in self._devices[WATCHDOG_DEVICES]:
if not hasattr(wd, 'address') or not hasattr(wd, 'alias'):
@@ -4525,14 +4519,13 @@
dev['address'] = address
dev['alias'] = alias
- def _getUnderlyingVideoDeviceInfo(self):
+ def _getUnderlyingVideoDeviceInfo(self, devicesXml):
"""
Obtain video devices info from libvirt.
"""
- videosxml = _domParseStr(self._lastXMLDesc).childNodes[0]. \
- getElementsByTagName('devices')[0].getElementsByTagName('video')
+ videosxml = devicesXml.getElementsByTagName('video')
for x in videosxml:
- alias = x.getElementsByTagName('alias')[0].getAttribute('name')
+ alias = self._getUnderlyingDeviceAliasName(x)
# Get video card address
address = self._getUnderlyingDeviceAddress(x)
@@ -4553,14 +4546,13 @@
dev['alias'] = alias
break
- def _getUnderlyingSoundDeviceInfo(self):
+ def _getUnderlyingSoundDeviceInfo(self, devicesXml):
"""
Obtain sound devices info from libvirt.
"""
- soundsxml = _domParseStr(self._lastXMLDesc).childNodes[0]. \
- getElementsByTagName('devices')[0].getElementsByTagName('sound')
+ soundsxml = devicesXml.getElementsByTagName('sound')
for x in soundsxml:
- alias = x.getElementsByTagName('alias')[0].getAttribute('name')
+ alias = self._getUnderlyingDeviceAliasName(x)
# Get sound card address
address = self._getUnderlyingDeviceAddress(x)
@@ -4581,12 +4573,11 @@
dev['alias'] = alias
break
- def _getUnderlyingDriveInfo(self):
+ def _getUnderlyingDriveInfo(self, devicesXml):
"""
Obtain block devices info from libvirt.
"""
- disksxml = _domParseStr(self._lastXMLDesc).childNodes[0]. \
- getElementsByTagName('devices')[0].getElementsByTagName('disk')
+ disksxml = devicesXml.getElementsByTagName('disk')
# FIXME! We need to gather as much info as possible from the libvirt.
# In the future we can return this real data to management instead of
# vm's conf
@@ -4600,7 +4591,7 @@
target = x.getElementsByTagName('target')
name = target[0].getAttribute('dev') if target else ''
- alias = x.getElementsByTagName('alias')[0].getAttribute('name')
+ alias = self._getUnderlyingDeviceAliasName(x)
readonly = bool(x.getElementsByTagName('readonly'))
boot = x.getElementsByTagName('boot')
bootOrder = boot[0].getAttribute('order') if boot else ''
@@ -4646,12 +4637,11 @@
diskDev['bootOrder'] = bootOrder
self.conf['devices'].append(diskDev)
- def _getUnderlyingDisplayPort(self):
+ def _getUnderlyingDisplayPort(self, xml):
"""
Obtain display port info from libvirt.
"""
- graphics = _domParseStr(self._lastXMLDesc).childNodes[0]. \
- getElementsByTagName('graphics')[0]
+ graphics = xml.childNodes[0].getElementsByTagName('graphics')[0]
port = graphics.getAttribute('port')
if port:
self.conf['displayPort'] = port
@@ -4659,18 +4649,16 @@
if port:
self.conf['displaySecurePort'] = port
- def _getUnderlyingNetworkInterfaceInfo(self):
+ def _getUnderlyingNetworkInterfaceInfo(self, devicesXml):
"""
Obtain network interface info from libvirt.
"""
# TODO use xpath instead of parseString (here and elsewhere)
- ifsxml = _domParseStr(self._lastXMLDesc).childNodes[0]. \
- getElementsByTagName('devices')[0]. \
- getElementsByTagName('interface')
+ ifsxml = devicesXml.getElementsByTagName('interface')
for x in ifsxml:
devType = x.getAttribute('type')
mac = x.getElementsByTagName('mac')[0].getAttribute('address')
- alias = x.getElementsByTagName('alias')[0].getAttribute('name')
+ alias = self._getUnderlyingDeviceAliasName(x)
if devType == 'hostdev':
name = alias
model = 'passthrough'
@@ -4802,8 +4790,7 @@
"during migration at destination host" %
devType)
- devices = _domParseStr(xml).childNodes[0]. \
- getElementsByTagName('devices')[0]
+ devices = self._getDevicesXml(parsedXml=_domParseStr(xml))
for deviceXML in devices.childNodes:
if deviceXML.nodeType != Node.ELEMENT_NODE:
--
To view, visit http://gerrit.ovirt.org/17694
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I7e106b2f2d3f4160d4e882f1a2880cb1b52fbb22
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Vinzenz Feenstra <vfeenstr(a)redhat.com>
9 years, 6 months
Change in vdsm[master]: add xmlrpcTests for cpu pinning
by lvroyce@linux.vnet.ibm.com
Royce Lv has uploaded a new change for review.
Change subject: add xmlrpcTests for cpu pinning
......................................................................
add xmlrpcTests for cpu pinning
Change-Id: Ia865f0d5eb4c9aabff6cef57b088c55df73a309e
Signed-off-by: Royce Lv<lvroyce(a)linux.vnet.ibm.com>
---
M tests/functional/xmlrpcTests.py
M tests/vdsClientTests.py
2 files changed, 40 insertions(+), 0 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/12/8412/1
diff --git a/tests/functional/xmlrpcTests.py b/tests/functional/xmlrpcTests.py
index 9c865db..2684d0f 100644
--- a/tests/functional/xmlrpcTests.py
+++ b/tests/functional/xmlrpcTests.py
@@ -174,3 +174,33 @@
destroyResult = self.s.destroy(VMID)
self.assertVdsOK(destroyResult)
+
+ def testCpuPin(self):
+ self.skipNoKVM()
+
+ def assertVMAndGuestUp():
+ self.assertVmUp(VMID)
+ self.assertGuestUp(VMID)
+
+ VMID = '77777777-ffff-3333-aaaa-222222222222'
+
+ with kernelBootImages() as (kernelPath, initramfsPath):
+ conf = {'display': 'vnc',
+ 'kernel': kernelPath,
+ 'initrd': initramfsPath,
+ 'kernelArgs': 'rd.break=cmdline rd.shell rd.skipfsck',
+ 'kvmEnable': 'true',
+ 'memSize': '256',
+ 'vmId': VMID,
+ 'vmName': 'vdsm_testPinVM',
+ 'vmType': 'kvm',
+ 'cpuPinning': {'emulator': '0', '0': '1'}}
+
+ try:
+ self.assertVdsOK(self.s.create(conf))
+ # wait 65 seconds for VM to come up until timeout
+ self.retryAssert(assertVMAndGuestUp, 65, 1)
+ finally:
+ destroyResult = self.s.destroy(VMID)
+
+ self.assertVdsOK(destroyResult)
diff --git a/tests/vdsClientTests.py b/tests/vdsClientTests.py
index abf3242..57e6e74 100644
--- a/tests/vdsClientTests.py
+++ b/tests/vdsClientTests.py
@@ -118,3 +118,13 @@
allArgs[-1] = 'cpuPinning={0:1,1:0}'
r4 = serv.do_create(['/dev/null'] + allArgs)
self.assertNotEquals(r4, expectResult)
+
+ # test just pin emulator
+ allArgs[-1] = "cpuPinning={emulator:1-3}"
+ r5 = serv.do_create(['/dev/null'] + allArgs)
+ self.assertEquals(r5['cpuPinning'],{'emulator':'1-3'})
+
+ # test pin emultor and vcpu
+ allArgs[-1] = "cpuPinning={emulator:1-3,1:0}"
+ r6 = serv.do_create(['/dev/null'] + allArgs)
+ self.assertEquals(r6['cpuPinning'],{'emulator':'1-3','1':'0'})
--
To view, visit http://gerrit.ovirt.org/8412
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ia865f0d5eb4c9aabff6cef57b088c55df73a309e
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Royce Lv <lvroyce(a)linux.vnet.ibm.com>
9 years, 7 months
Change in vdsm[master]: [WIP]add simple balloon functional testcase
by lvroyce@linux.vnet.ibm.com
Royce Lv has uploaded a new change for review.
Change subject: [WIP]add simple balloon functional testcase
......................................................................
[WIP]add simple balloon functional testcase
Change-Id: Ie8140fe1c754d9d4026c503a19420e6552a3f4fe
Signed-off-by: Royce Lv<lvroyce(a)linux.vnet.ibm.com>
---
M tests/functional/xmlrpcTests.py
1 file changed, 34 insertions(+), 0 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/20/12820/1
diff --git a/tests/functional/xmlrpcTests.py b/tests/functional/xmlrpcTests.py
index 3eb65e4..88dd2c5 100644
--- a/tests/functional/xmlrpcTests.py
+++ b/tests/functional/xmlrpcTests.py
@@ -19,6 +19,7 @@
#
import os
+import time
import tempfile
import pwd
import grp
@@ -29,6 +30,7 @@
from testrunner import VdsmTestCase as TestCaseBase
from testrunner import permutations, expandPermutations
from nose.plugins.skip import SkipTest
+from momTests import skipNoMOM
try:
import rtslib
except ImportError:
@@ -169,6 +171,38 @@
with RollbackContext() as rollback:
self._runVMKernelBootTemplate(rollback, customization)
+ @skipNoKVM
+ @skipNoMOM
+ def testSmallVMBallooning(self):
+ policyStr = """
+ (def set_guest (guest)
+ {
+ (guest.Control "balloon_target" 0)
+ })
+ (with Guests guest (set_guest guest))"""
+ balloonSpec = {'device': 'memballoon',
+ 'type': 'balloon',
+ 'specParams': {'model': 'virtio'}}
+ customization = {'vmId': '77777777-ffff-3333-bbbb-555555555555',
+ 'vmName': 'vdsm_testBalloonVM',
+ 'devices': [balloonSpec]}
+ policy = {'balloon': policyStr}
+
+ with RollbackContext() as rollback:
+ self._runVMKernelBootTemplate(rollback, customization)
+ self._enableBalloonPolicy(policy, rollback)
+ time.sleep(12) # MOM policy engine wake up evey 10s
+ balloonInf = self.s.getVmStats(
+ customization['vmId'])['statsList'][0]['balloonInfo']
+ self.assertEqual(balloonInf['balloon_cur'], 0)
+
+ def _enableBalloonPolicy(self, policy, rollback):
+ r = self.s.setMOMPolicy(policy)
+ self.assertVdsOK(r)
+ undo = lambda: \
+ self.assertVdsOK(self.s.resetMOMPolicy())
+ rollback.prependDefer(undo)
+
def _runVMKernelBootTemplate(self, rollback, vmDef={}, distro='fedora'):
kernelArgsDistro = {
# Fedora: The initramfs is generated by dracut. The following
--
To view, visit http://gerrit.ovirt.org/12820
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ie8140fe1c754d9d4026c503a19420e6552a3f4fe
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Royce Lv <lvroyce(a)linux.vnet.ibm.com>
9 years, 7 months
Change in vdsm[master]: Avoid redundant volume produces.
by ewarszaw@redhat.com
Eduardo has uploaded a new change for review.
Change subject: Avoid redundant volume produces.
......................................................................
Avoid redundant volume produces.
Add sd.getVolumePath() returns the volume path without produce it.
Deprecating hsm.getVolumePath() and hsm.prepareVolume().
When removed, remove API.prepare(), BindingXMLRPC.volumePrepare(),
API.getPath, BindingXMLRPC.volumeGetPath(), etc.
Change-Id: I3ad53a7e8a66d7f9bdd62048f2bf1f722a490c5c
Signed-off-by: Eduardo <ewarszaw(a)redhat.com>
---
M vdsm/storage/fileSD.py
M vdsm/storage/hsm.py
M vdsm/storage/sd.py
3 files changed, 11 insertions(+), 6 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/91/17991/1
diff --git a/vdsm/storage/fileSD.py b/vdsm/storage/fileSD.py
index 9d1493d..8cbea23 100644
--- a/vdsm/storage/fileSD.py
+++ b/vdsm/storage/fileSD.py
@@ -302,8 +302,7 @@
Return the volume lease (leasePath, leaseOffset)
"""
if self.hasVolumeLeases():
- vol = self.produceVolume(imgUUID, volUUID)
- volumePath = vol.getVolumePath()
+ volumePath = self.getVolumePath(imgUUID, volUUID)
leasePath = volumePath + fileVolume.LEASE_FILEEXT
return leasePath, fileVolume.LEASE_FILEOFFSET
return None, None
@@ -426,8 +425,9 @@
# NFS volumes. In theory it is necessary to fix the permission
# of the leaf only but to not introduce an additional requirement
# (ordered volUUIDs) we fix them all.
- for vol in [self.produceVolume(imgUUID, x) for x in volUUIDs]:
- self.oop.fileUtils.copyUserModeToGroup(vol.getVolumePath())
+ for volUUID in volUUIDs:
+ volPath = self.getVolumePath(imgUUID, volUUID)
+ self.oop.fileUtils.copyUserModeToGroup(volPath)
@classmethod
def format(cls, sdUUID):
diff --git a/vdsm/storage/hsm.py b/vdsm/storage/hsm.py
index c754ee8..3545677 100644
--- a/vdsm/storage/hsm.py
+++ b/vdsm/storage/hsm.py
@@ -3076,6 +3076,7 @@
volUUID=volUUID).getInfo()
return dict(info=info)
+ @deprecated
@public
def getVolumePath(self, sdUUID, spUUID, imgUUID, volUUID, options=None):
"""
@@ -3100,8 +3101,7 @@
"""
vars.task.getSharedLock(STORAGE, sdUUID)
path = sdCache.produce(
- sdUUID=sdUUID).produceVolume(imgUUID=imgUUID,
- volUUID=volUUID).getVolumePath()
+ sdUUID=sdUUID).getVolumePath(imgUUID, volUUID)
return dict(path=path)
@public
@@ -3127,6 +3127,7 @@
if fails:
self.log.error("Failed to remove the following rules: %s", fails)
+ @deprecated
@public
def prepareVolume(self, sdUUID, spUUID, imgUUID, volUUID, rw=True,
options=None):
diff --git a/vdsm/storage/sd.py b/vdsm/storage/sd.py
index 36c4877..dde7832 100644
--- a/vdsm/storage/sd.py
+++ b/vdsm/storage/sd.py
@@ -640,6 +640,10 @@
# If it has a repo we don't have multiple domains. Assume single pool
return os.path.join(self.storage_repository, self.getPools()[0])
+ def getVolumePath(self, imgUUID, volUUID):
+ return os.path.join(self.mountpoint, self.sdUUID, 'images', imgUUID,
+ volUUID)
+
def getIsoDomainImagesDir(self):
"""
Get 'images' directory from Iso domain
--
To view, visit http://gerrit.ovirt.org/17991
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I3ad53a7e8a66d7f9bdd62048f2bf1f722a490c5c
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Eduardo <ewarszaw(a)redhat.com>
9 years, 9 months
Change in vdsm[master]: [WIP] Towards a more (block) secure HSM.
by ewarszaw@redhat.com
Eduardo has uploaded a new change for review.
Change subject: [WIP] Towards a more (block) secure HSM.
......................................................................
[WIP] Towards a more (block) secure HSM.
Change-Id: I30df4ee5cdb6b44cf14d8cb155436aac7442a07d
---
M vdsm/storage/hsm.py
M vdsm/storage/lvm.py
M vdsm/storage/sp.py
3 files changed, 25 insertions(+), 5 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/18/2218/1
--
To view, visit http://gerrit.ovirt.org/2218
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I30df4ee5cdb6b44cf14d8cb155436aac7442a07d
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Eduardo <ewarszaw(a)redhat.com>
9 years, 9 months
Change in vdsm[master]: gluster: [WIP]Get size information of gluster volume
by avishwan@redhat.com
Aravinda VK has uploaded a new change for review.
Change subject: gluster: [WIP]Get size information of gluster volume
......................................................................
gluster: [WIP]Get size information of gluster volume
Change-Id: I358d4f3bf793ecc1a01e0592d68919d1405f6e19
Signed-off-by: Aravinda VK <avishwan(a)redhat.com>
---
M client/vdsClientGluster.py
M vdsm.spec.in
M vdsm/gluster/Makefile.am
M vdsm/gluster/__init__.py
M vdsm/gluster/api.py
A vdsm/gluster/gfapi.py
6 files changed, 100 insertions(+), 1 deletion(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/22/17822/1
diff --git a/client/vdsClientGluster.py b/client/vdsClientGluster.py
index 90af83e..644bfe3 100644
--- a/client/vdsClientGluster.py
+++ b/client/vdsClientGluster.py
@@ -424,6 +424,17 @@
pp.pprint(status)
return status['status']['code'], status['status']['message']
+ def do_glusterVolumeSize(self, args):
+ params = self._eqSplit(args)
+ try:
+ volumeName = params.get('volumeName', '')
+ except:
+ raise ValueError
+
+ status = self.s.glusterVolumeSize(volumeName)
+ pp.pprint(status)
+ return status['status']['code'], status['status']['message']
+
def getGlusterCmdDict(serv):
return \
@@ -705,4 +716,9 @@
'not set'
'(swift, glusterd, smb, memcached)'
)),
+ 'glusterVolumeSize': (
+ serv.do_glusterVolumeSize,
+ ('volumeName=<volume name>',
+ 'Returns total, available and used space status of gluster volume'
+ )),
}
diff --git a/vdsm.spec.in b/vdsm.spec.in
index 21b3565..e49e102 100644
--- a/vdsm.spec.in
+++ b/vdsm.spec.in
@@ -1271,6 +1271,7 @@
%doc COPYING
%{_datadir}/%{vdsm_name}/gluster/api.py*
%{_datadir}/%{vdsm_name}/gluster/vdsmapi-gluster-schema.json
+%{_datadir}/%{vdsm_name}/gluster/gfapi.py*
%{_datadir}/%{vdsm_name}/gluster/hooks.py*
%{_datadir}/%{vdsm_name}/gluster/services.py*
%endif
diff --git a/vdsm/gluster/Makefile.am b/vdsm/gluster/Makefile.am
index dd5434d..9c2989f 100644
--- a/vdsm/gluster/Makefile.am
+++ b/vdsm/gluster/Makefile.am
@@ -26,6 +26,7 @@
api.py \
cli.py \
exception.py \
+ gfapi.py \
hooks.py \
hostname.py \
services.py \
diff --git a/vdsm/gluster/__init__.py b/vdsm/gluster/__init__.py
index bec70ea..e5a2fd6 100644
--- a/vdsm/gluster/__init__.py
+++ b/vdsm/gluster/__init__.py
@@ -22,7 +22,7 @@
import tempfile
from functools import wraps
-MODULE_LIST = ('cli', 'hooks', 'services')
+MODULE_LIST = ('cli', 'hooks', 'services', 'gfapi')
def makePublic(func):
diff --git a/vdsm/gluster/api.py b/vdsm/gluster/api.py
index 4bd8308..89546c1 100644
--- a/vdsm/gluster/api.py
+++ b/vdsm/gluster/api.py
@@ -287,6 +287,22 @@
status = self.svdsmProxy.glusterServicesGet(serviceNames)
return {'services': status}
+ @exportAsVerb
+ def volumeSize(self, volumeName, options=None):
+ data = self.svdsmProxy.glusterVolumeStatvfs(volumeName)
+ # f_blocks = Total number of blocks
+ # f_bfree = Total number of blocks free
+ # f_bavail = Total number of blocks available for non root user
+ # total blocks available = f_blocks - (f_bfree - f_bavail)
+ total_blocks_available = data['f_blocks'] - \
+ (data['f_bfree'] - data['f_bavail'])
+ return {
+ 'total': total_blocks_available * data.f_bsize / 1024,
+ 'free': data['f_bavail'] * data['f_bsize'] / 1024,
+ 'used': (total_blocks_available - data['f_bavail']) * \
+ data['f_bsize'] / 1024
+ }
+
def getGlusterMethods(gluster):
l = []
diff --git a/vdsm/gluster/gfapi.py b/vdsm/gluster/gfapi.py
new file mode 100644
index 0000000..abfdabd
--- /dev/null
+++ b/vdsm/gluster/gfapi.py
@@ -0,0 +1,65 @@
+#
+# Copyright 2013 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
+#
+from ctypes import *
+
+# import exception as ge
+from . import makePublic
+
+GLUSTER_VOL_PROTOCAL='tcp'
+GLUSTER_VOL_HOST='localhost'
+GLUSTER_VOL_PORT=24007
+
+class Stat (Structure):
+ _fields_ = [
+ ('f_bsize', c_ulong),
+ ('f_frsize', c_ulong),
+ ('f_blocks', c_ulong),
+ ('f_bfree', c_ulong),
+ ('f_bavail', c_ulong),
+ ('f_files', c_ulong),
+ ('f_ffree', c_ulong),
+ ('f_favail', c_ulong),
+ ('f_fsid', c_ulong),
+ ('f_flag', c_ulong),
+ ('f_namemax', c_ulong),
+ ('__f_spare', c_int * 6),
+ ]
+
+
+api = CDLL("libgfapi.so",RTLD_GLOBAL)
+api.glfs_statvfs.restype = c_int
+api.glfs_statvfs.argtypes = [c_void_p, c_char_p, POINTER(Stat)]
+
+@makePublic
+def volumeStatvfs(volumeId):
+ path = "/"
+ fs = api.glfs_new(volumeId)
+ api.glfs_set_volfile_server(fs,
+ GLUSTER_VOL_PROTOCAL,
+ GLUSTER_VOL_HOST,
+ GLUSTER_VOL_PORT)
+ api.glfs_init(fs)
+
+ x = Stat()
+ rc = api.glfs_statvfs(fs, path, byref(x))
+ statvfsData = {}
+ for k in x._fields_:
+ statvfsData[k[0]] = getattr(x, k[0])
+ return statvfsData
--
To view, visit http://gerrit.ovirt.org/17822
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I358d4f3bf793ecc1a01e0592d68919d1405f6e19
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Aravinda VK <avishwan(a)redhat.com>
9 years, 9 months
Change in vdsm[master]: Add hostusbdirect hook to vdsm_hooks.
by lyarwood@redhat.com
Lee Yarwood has uploaded a new change for review.
Change subject: Add hostusbdirect hook to vdsm_hooks.
......................................................................
Add hostusbdirect hook to vdsm_hooks.
This is a slight variation of the hostusb hook. This version uses the bus and
device IDs to attach host USB device to the guest using the following libvirt XML :
<hostdev mode='subsystem' type='usb' managed='yes'>
<source>
<address bus='001' device='003'/>
</source>
</hostdev>
In the future this could be merged with the hostusb hook.
Change-Id: I00b4b03993cd7290462b0e17457892b23dd41b31
Signed-off-by: Lee Yarwood <lyarwood(a)redhat.com>
---
M configure.ac
M vdsm.spec.in
M vdsm_hooks/Makefile.am
A vdsm_hooks/hostusbdirect/Makefile.am
A vdsm_hooks/hostusbdirect/README
A vdsm_hooks/hostusbdirect/after_vm_destroy.py
A vdsm_hooks/hostusbdirect/before_vm_migrate_source.py
A vdsm_hooks/hostusbdirect/before_vm_start.py
A vdsm_hooks/hostusbdirect/sudoers.vdsm_hook_hostusbdirect
9 files changed, 262 insertions(+), 0 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/28/17428/1
diff --git a/configure.ac b/configure.ac
index 0ccca95..39e31f0 100644
--- a/configure.ac
+++ b/configure.ac
@@ -225,6 +225,7 @@
vdsm_hooks/fileinject/Makefile
vdsm_hooks/floppy/Makefile
vdsm_hooks/hostusb/Makefile
+ vdsm_hooks/hostusbdirect/Makefile
vdsm_hooks/hugepages/Makefile
vdsm_hooks/isolatedprivatevlan/Makefile
vdsm_hooks/macspoof/Makefile
diff --git a/vdsm.spec.in b/vdsm.spec.in
index 235d1db..c1b9431 100644
--- a/vdsm.spec.in
+++ b/vdsm.spec.in
@@ -389,6 +389,15 @@
Hook is getting vendor and product id of USB device
disconnect it from host and attach it to VM
+%package hook-hostusb-direct
+Summary: Allow attaching USB device from host by bus and device ids.
+BuildArch: noarch
+Requires: usbutils
+
+%description hook-hostusb-direct
+Hook is getting bus and device id of USB device
+disconnect it from host and attach it to VM
+
%package hook-hugepages
Summary: Huge pages enable user to handle VM with 2048KB page files.
BuildArch: noarch
diff --git a/vdsm_hooks/Makefile.am b/vdsm_hooks/Makefile.am
index 8a8d594..fb4052b 100644
--- a/vdsm_hooks/Makefile.am
+++ b/vdsm_hooks/Makefile.am
@@ -30,6 +30,7 @@
fileinject \
floppy \
hostusb \
+ hostusbdirect \
hugepages \
isolatedprivatevlan \
macspoof \
diff --git a/vdsm_hooks/hostusbdirect/Makefile.am b/vdsm_hooks/hostusbdirect/Makefile.am
new file mode 100644
index 0000000..9d0cdbc
--- /dev/null
+++ b/vdsm_hooks/hostusbdirect/Makefile.am
@@ -0,0 +1,52 @@
+#
+# Copyright 2013 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
+#
+
+EXTRA_DIST = \
+ after_vm_destroy.py \
+ before_vm_migrate_source.py \
+ before_vm_start.py \
+ sudoers.vdsm_hook_hostusbdirect
+
+install-data-hook:
+ chmod 440 $(DESTDIR)$(sysconfdir)/sudoers.d/50_vdsm_hook_hostusbdirect
+
+install-data-local: install-data-sudoers
+ $(MKDIR_P) $(DESTDIR)$(vdsmhooksdir)/before_vm_start
+ $(INSTALL_SCRIPT) $(srcdir)/before_vm_start.py \
+ $(DESTDIR)$(vdsmhooksdir)/before_vm_start/50_hostusbdirect
+ $(MKDIR_P) $(DESTDIR)$(vdsmhooksdir)/after_vm_destroy
+ $(INSTALL_SCRIPT) $(srcdir)/after_vm_destroy.py \
+ $(DESTDIR)$(vdsmhooksdir)/after_vm_destroy/50_hostusbdirect
+ $(MKDIR_P) $(DESTDIR)$(vdsmhooksdir)/before_vm_migrate_source
+ $(INSTALL_SCRIPT) $(srcdir)/before_vm_migrate_source.py \
+ $(DESTDIR)$(vdsmhooksdir)/before_vm_migrate_source/50_hostusbdirect
+
+uninstall-local: uninstall-data-sudoers
+ $(RM) $(DESTDIR)$(vdsmhooksdir)/before_vm_start/50_hostusbdirect
+ $(RM) $(DESTDIR)$(vdsmhooksdir)/after_vm_destroy/50_hostusbdirect
+ $(RM) $(DESTDIR)$(vdsmhooksdir)/before_vm_migrate_source/50_hostusbdirect
+
+install-data-sudoers:
+ $(MKDIR_P) $(DESTDIR)$(sysconfdir)/sudoers.d
+ $(INSTALL_DATA) $(srcdir)/sudoers.vdsm_hook_hostusbdirect \
+ $(DESTDIR)$(sysconfdir)/sudoers.d/50_vdsm_hook_hostusbdirect
+
+uninstall-data-sudoers:
+ $(RM) $(DESTDIR)$(sysconfdir)/sudoers.d/50_vdsm_hook_hostusbdirect
diff --git a/vdsm_hooks/hostusbdirect/README b/vdsm_hooks/hostusbdirect/README
new file mode 100644
index 0000000..297c559
--- /dev/null
+++ b/vdsm_hooks/hostusbdirect/README
@@ -0,0 +1,18 @@
+host usb hook direct
+====================
+add hosts usb device/s to VM using bus and device ids:
+
+<hostdev mode='subsystem' type='usb'>
+ <source>
+ <address bus='001' device='003'/>
+ </source>
+</hostdev>
+
+syntax:
+ hostusbdirect=001:003&001:002
+ i.e.
+ hostusb=bus:device (can add more then one with '&' separator)
+
+Note:
+ The VM must be pinned to host and this hook will
+ fail any migration attempt.
diff --git a/vdsm_hooks/hostusbdirect/after_vm_destroy.py b/vdsm_hooks/hostusbdirect/after_vm_destroy.py
new file mode 100755
index 0000000..3882347
--- /dev/null
+++ b/vdsm_hooks/hostusbdirect/after_vm_destroy.py
@@ -0,0 +1,64 @@
+#!/usr/bin/python
+
+import os
+import sys
+import traceback
+
+import hooking
+
+'''
+after_vm_destroy:
+return the original owner of the usb device
+'''
+
+HOOK_HOSTUSB_PATH = '/var/run/vdsm/hooks/hostusbdirect-permissions'
+
+
+def get_owner(devpath):
+ uid = pid = -1
+ content = ''
+
+ if not os.path.isfile(HOOK_HOSTUSB_PATH):
+ return uid, pid
+
+ f = file(HOOK_HOSTUSB_PATH, 'r')
+ for line in f:
+ if len(line) > 0 and line.split(':')[0] == devpath:
+ entry = line.split(':')
+ uid = entry[1]
+ pid = entry[2]
+ elif len(line) > 0:
+ content += line + '\n'
+
+ f.close()
+ if uid != -1:
+ f = file(HOOK_HOSTUSB_PATH, 'w')
+ f.writelines(content)
+ f.close()
+
+ return uid, pid
+
+
+def chown(bus, device):
+ devpath = '/dev/bus/usb/' + bus + '/' + device
+ uid, gid = get_owner(devpath)
+
+ owner = str(uid) + ':' + str(gid)
+ command = ['/bin/chown', owner, devpath]
+ retcode, out, err = hooking.execCmd(command, sudo=True, raw=True)
+ if retcode != 0:
+ sys.stderr.write('hostusbdirect: error chown %s to %s, err = %s\n' %
+ (devpath, owner, err))
+ sys.exit(2)
+
+
+if 'hostusbdirect' in os.environ:
+ try:
+ for usb in os.environ['hostusbdirect'].split('&'):
+ bus, device = usb.split(':')
+ chown(bus, device)
+
+ except:
+ sys.stderr.write('hostusb after_vm_destroy: [unexpected error]: %s\n' %
+ traceback.format_exc())
+ sys.exit(2)
diff --git a/vdsm_hooks/hostusbdirect/before_vm_migrate_source.py b/vdsm_hooks/hostusbdirect/before_vm_migrate_source.py
new file mode 100755
index 0000000..43a2eca
--- /dev/null
+++ b/vdsm_hooks/hostusbdirect/before_vm_migrate_source.py
@@ -0,0 +1,8 @@
+#!/usr/bin/python
+
+import os
+import sys
+
+if 'hostusbdirect' in os.environ:
+ sys.stderr.write("hostusbdirect: can't migrate VM with host usb devices\n")
+ sys.exit(2)
diff --git a/vdsm_hooks/hostusbdirect/before_vm_start.py b/vdsm_hooks/hostusbdirect/before_vm_start.py
new file mode 100755
index 0000000..57307aa
--- /dev/null
+++ b/vdsm_hooks/hostusbdirect/before_vm_start.py
@@ -0,0 +1,108 @@
+#!/usr/bin/python
+
+import os
+import sys
+import grp
+import pwd
+import traceback
+
+import hooking
+
+'''
+host usb hook direct
+====================
+
+syntax:
+ hostusbdirect=001:001&001:002
+ i.e.
+ hostusbdirect=bus:device (can add more then one with '&' separator)
+
+Note:
+ The VM must be pinned to host and this hook will
+ fail any migration attempt.
+'''
+
+HOOK_HOSTUSB_PATH = '/var/run/vdsm/hooks/hostusbdirect-permissions'
+
+
+def log_dev_owner(devpath, user, group):
+ entry = devpath + ":" + str(user) + ":" + str(group)
+
+ if not os.path.isdir(os.path.dirname(HOOK_HOSTUSB_PATH)):
+ os.mkdir(os.path.dirname(HOOK_HOSTUSB_PATH))
+
+ if os.path.isfile(HOOK_HOSTUSB_PATH):
+ f = file(HOOK_HOSTUSB_PATH, 'r')
+ for line in f:
+ if entry == line:
+ f.close()
+ return
+
+ f = file(HOOK_HOSTUSB_PATH, 'a')
+ f.writelines(entry)
+ f.close()
+
+
+def chown(bus, device):
+
+ devpath = '/dev/bus/usb/' + bus + '/' + device
+ stat = os.stat(devpath)
+
+ group = grp.getgrnam('qemu')
+ gid = group.gr_gid
+ user = pwd.getpwnam('qemu')
+ uid = user.pw_uid
+
+ owner = str(uid) + ':' + str(gid)
+ command = ['/bin/chown', owner, devpath]
+ retcode, out, err = hooking.execCmd(command, sudo=True, raw=True)
+ if retcode != 0:
+ sys.stderr.write('hostusbdirect: error chown %s to %s, err = %s\n' %
+ (devpath, owner, err))
+ sys.exit(2)
+
+ log_dev_owner(devpath, stat.st_uid, stat.st_gid)
+
+
+def add_devices(domxml, devices):
+ domain = domxml.getElementsByTagName('devices')[0]
+
+ for device in devices:
+ # Add the following for each device :
+ #<hostdev mode='subsystem' type='usb' managed='yes'>
+ # <source>
+ # <address bus='001' device='003'/>
+ # </source>
+ #</hostdev>
+
+ hostdev = domxml.createElement('hostdev')
+ hostdev.setAttribute('mode', 'subsystem')
+ hostdev.setAttribute('type', 'usb')
+ hostdev.setAttribute('managed', 'yes')
+
+ source = domxml.createElement('source')
+ hostdev.appendChild(source)
+
+ address = domxml.createElement('address')
+ address.setAttribute('bus', device['bus'])
+ address.setAttribute('device', device['device'])
+ source.appendChild(address)
+
+ domain.appendChild(hostdev)
+
+if 'usbhostdirect' in os.environ:
+ try:
+ domxml = hooking.read_domxml()
+ devices = []
+
+ for usb in os.environ['usbhostdirect'].split('&'):
+ bus, device = usb.split(':')
+ chown(bus, device)
+ devices.append({'bus': bus, 'device': device})
+
+ add_devices(domxml, devices)
+ hooking.write_domxml(domxml)
+ except:
+ sys.stderr.write('hostusbdirect: [unexpected error]: %s\n' %
+ traceback.format_exc())
+ sys.exit(2)
diff --git a/vdsm_hooks/hostusbdirect/sudoers.vdsm_hook_hostusbdirect b/vdsm_hooks/hostusbdirect/sudoers.vdsm_hook_hostusbdirect
new file mode 100644
index 0000000..cba601d
--- /dev/null
+++ b/vdsm_hooks/hostusbdirect/sudoers.vdsm_hook_hostusbdirect
@@ -0,0 +1 @@
+vdsm ALL=(ALL) NOPASSWD: /bin/chown
--
To view, visit http://gerrit.ovirt.org/17428
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I00b4b03993cd7290462b0e17457892b23dd41b31
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Lee Yarwood <lyarwood(a)redhat.com>
9 years, 10 months