Change in vdsm[master]: Qos feature: Adds bandwidth definition at configuration leve...
gvallare at redhat.com
gvallare at redhat.com
Fri Jun 14 14:05:59 UTC 2013
Giuseppe Vallarelli has uploaded a new change for review.
Change subject: Qos feature: Adds bandwidth definition at configuration level.
......................................................................
Qos feature: Adds bandwidth definition at configuration level.
Network definition when configuring libvirt network is enriched with
the optional bandwidth parameters for traffic shaping. Patch includes
a refactoring of the xml generation and some tests.
Change-Id: If0c3b4b9a6fd5eb53579fb2e157b5325caa88d04
Signed-off-by: Giuseppe Vallarelli <gvallare at redhat.com>
---
M tests/netconfTests.py
M vdsm/configNetwork.py
M vdsm/netconf/ifcfg.py
M vdsm_api/vdsmapi-schema.json
4 files changed, 140 insertions(+), 42 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/24/15724/1
diff --git a/tests/netconfTests.py b/tests/netconfTests.py
index 26d8ac2..a8a777a 100644
--- a/tests/netconfTests.py
+++ b/tests/netconfTests.py
@@ -25,6 +25,7 @@
import shutil
import subprocess
import tempfile
+from xml.etree import ElementTree
from vdsm import netinfo
from netconf import ifcfg
@@ -70,17 +71,27 @@
restoredContent = file(fn).read()
self.assertEqual(content, restoredContent)
+ def assertEqualXml(self, a, b):
+ """
+ Compare two xml artifacts for equality.
+ """
+ contents_a = ElementTree.tostring(ElementTree.fromstring(a))
+ contents_b = ElementTree.tostring(ElementTree.fromstring(b))
+ return contents_a == contents_b
+
+ def setUp(self):
+ self.cw = ifcfg.ConfigWriter()
+
@MonkeyPatch(subprocess, 'Popen', lambda x: None)
def testAtomicRestore(self):
- cw = ifcfg.ConfigWriter()
self._createFiles()
for fn, _, _ in self._files:
- cw._atomicBackup(fn)
+ self.cw._atomicBackup(fn)
self._makeFilesDirty()
- cw.restoreAtomicBackup()
+ self.cw.restoreAtomicBackup()
self._assertFilesRestored()
@MonkeyPatch(os, 'chown', lambda *x: 0)
@@ -105,15 +116,56 @@
raise SkipTest("'vdsm' is not in user account database, "
"install vdsm package to create the vdsm user")
- cw = ifcfg.ConfigWriter()
self._createFiles()
for fn, _, _ in self._files:
- cw._persistentBackup(fn)
+ self.cw._persistentBackup(fn)
self._makeFilesDirty()
- cw = ifcfg.ConfigWriter()
- cw.restorePersistentBackup()
+ self.cw.restorePersistentBackup()
self._assertFilesRestored()
+
+ def testCreateNetXmlBridged(self):
+ netName = "awesome_net"
+ network = "dummy"
+ expectedDoc = ("""<network>
+ <name>%s</name>
+ <forward mode='bridge'/>
+ <bridge name='%s'/>
+ </network>""" % (netName, network))
+ actualDoc = self.cw.createNetXml(netName, network, True, None)
+
+ self.assertEqualXml(expectedDoc, actualDoc)
+
+ def testCreateNetXml(self):
+ netName = "awesome_net"
+ iface = "dummy"
+ expectedDoc = ("""<network>
+ <name>%s</name>
+ <forward mode='passthrough'/>
+ <interface dev='%s'/>
+ </network>""" % (netName, iface))
+ actualDoc = self.cw.createNetXml(netName, None, False, iface)
+
+ self.assertEqualXml(expectedDoc, actualDoc)
+
+ def testCreateNetXmlBridgedQos(self):
+ netName = "awesome_net"
+ network = "dummy"
+ inbound = {'average': '1024', 'burst': '5000'}
+ expectedDoc = ("""<network>
+ <name>%s</name>
+ <forward mode='bridge'/>
+ <bridge name='%s'/>
+ <bandwidth>
+ <inbound average='%s' burst='%s' />
+ </bandwidth>
+ </network>"""
+ % (netName, network,
+ inbound['average'], inbound['burst']))
+ actualDoc = self.cw.createNetXml(netName, network,
+ True, None, qosInbound=inbound)
+
+ self.assertEqualXml(expectedDoc, actualDoc)
diff --git a/vdsm/configNetwork.py b/vdsm/configNetwork.py
index 68025f2..6f69f76 100755
--- a/vdsm/configNetwork.py
+++ b/vdsm/configNetwork.py
@@ -150,7 +150,7 @@
def addNetwork(network, vlan=None, bonding=None, nics=None, ipaddr=None,
netmask=None, prefix=None, mtu=None, gateway=None, force=False,
configWriter=None, bondingOptions=None, bridged=True,
- _netinfo=None, **options):
+ _netinfo=None, qosInbound=None, qosOutbound=None, **options):
nics = nics or ()
if _netinfo is None:
_netinfo = netinfo.NetInfo()
@@ -198,7 +198,8 @@
gateway, bootproto, _netinfo, configurator,
**options)
netEnt.configure(**options)
- configurator.configureLibvirtNetwork(network, netEnt)
+ configurator.configureLibvirtNetwork(network, netEnt, qosInbound,
+ qosOutbound)
def assertBridgeClean(bridge, vlan, bonding, nics):
diff --git a/vdsm/netconf/ifcfg.py b/vdsm/netconf/ifcfg.py
index 296b042..2c8c2b3 100644
--- a/vdsm/netconf/ifcfg.py
+++ b/vdsm/netconf/ifcfg.py
@@ -18,6 +18,7 @@
#
from xml.sax.saxutils import escape
+from xml.etree.ElementTree import Element as XmlElement, tostring
import glob
import libvirt
import logging
@@ -109,10 +110,12 @@
ifdown(nic.name)
ifup(nic.name, async)
- def configureLibvirtNetwork(self, network, iface):
+ def configureLibvirtNetwork(self, network, iface, qosInbound=None,
+ qosOutbound=None):
self.configWriter.createLibvirtNetwork(network,
isinstance(iface, Bridge),
- iface.name)
+ iface.name, qosInbound,
+ qosOutbound)
self._libvirtAdded.add(network)
def configureBonding(self, bond, nics, bridge=None, mtu=None,
@@ -243,18 +246,51 @@
net.create()
net.setAutostart(1)
+ def createNetXml(self, netName, network, bridged, iface,
+ qosInbound=None, qosOutbound=None):
+ """
+ Creates Network Xml e.g.:
+ <network>
+ <name>dummy</name>
+ <forward mode='bridge' || 'passthrough'/>
+ <bridge name='awesome'/> || <interface dev='awesome'/>
+ [<inbound average='1000' [peak='5000'] [burst='1024']/>]
+ [<outbound average='1000' burst='1024'/>]
+ </network>
+
+ Forward mode can be either bridge or passthrough,
+ according to net if bridged or bridgeless this
+ determines respectively the presence of bridge
+ or interface element. Inbound or outbound element
+ can be optionally defined.
+ """
+
+ root = XmlElement('network')
+ nameElem = XmlElement('name')
+ nameElem.text = escape(netName)
+ forwardElem = XmlElement('forward',
+ mode='bridge' if bridged else 'passthrough')
+ root.append(nameElem)
+ root.append(forwardElem)
+ root.append(XmlElement('bridge', name=escape(network))
+ if bridged else XmlElement('interface', dev=escape(iface)))
+
+ if qosInbound or qosOutbound:
+ bandwidthElem = XmlElement('bandwidth')
+ if qosInbound:
+ bandwidthElem.append(XmlElement('inbound', **qosInbound))
+ if qosOutbound:
+ bandwidthElem.append(XmlElement('outbound', **qosOutbound))
+ root.append(bandwidthElem)
+
+ return tostring(root)
+
def createLibvirtNetwork(self, network, bridged=True, iface=None,
- skipBackup=False):
+ skipBackup=False, qosInbound=None,
+ qosOutbound=None):
netName = netinfo.LIBVIRT_NET_PREFIX + network
- if bridged:
- netXml = '''<network><name>%s</name><forward mode='bridge'/>
- <bridge name='%s'/></network>''' % (escape(netName),
- escape(network))
- else:
- netXml = (
- '''<network><name>%s</name><forward mode='passthrough'>'''
- '''<interface dev='%s'/></forward></network>''' %
- (escape(netName), escape(iface)))
+ netXml = self.createNetXml(netName, network, bridged, iface,
+ qosInbound, qosOutbound)
if not skipBackup:
self._networkBackup(network)
self._createNetwork(netXml)
@@ -564,7 +600,6 @@
conf = 'VLAN=yes\n'
if bridge:
conf += 'BRIDGE=%s\n' % pipes.quote(bridge)
-
self._createConfFile(conf, vlan, ipaddr, netmask, gateway,
bootproto, mtu, onboot, **kwargs)
diff --git a/vdsm_api/vdsmapi-schema.json b/vdsm_api/vdsmapi-schema.json
index a87dc56..85f63a6 100644
--- a/vdsm_api/vdsmapi-schema.json
+++ b/vdsm_api/vdsmapi-schema.json
@@ -63,27 +63,32 @@
#
# @bondingOptions: #optional A string of space-separated <option>=<value> pairs
#
+# @qosInbound: #optional VmInterfaceDeviceBandwidthParams for incoming traffic.
+#
+# @qosOutbound: #optional VmInterfaceDeviceBandwidthParams for outgoing traffic.
+#
# Since: 4.10.0
##
{'type': 'NetworkOptions',
'data': {'*ipaddr': 'str', '*netmask': 'str', '*gateway': 'str',
'*bootproto': 'str', '*delay': 'uint', '*onboot': 'str',
- '*bondingOptions', 'str'}}
+ '*bondingOptions', 'str', '*qosInbound': 'VmInterfaceDeviceBandwidthParams',
+ '*qosOutbound': 'VmInterfaceDeviceBandwidthParams'}}
##
# @Host.addNetwork:
#
# Add a new network to this host.
#
-# @bridge: The name of the bridge device
+# @bridge: The name of the bridge device
#
-# @vlan: #optional The name of a VLAN to create on the device
+# @vlan: #optional The name of a VLAN to create on the device
#
-# @bond: #optional The name of a bond device to create from @nics
+# @bond: #optional The name of a bond device to create from @nics
#
-# @nics: #optional A list of network device names
+# @nics: #optional A list of network device names
#
-# @options: #optional A @NetworkOptions structure
+# @options: #optional A @NetworkOptions structure
#
# Since: 4.10.0
##
@@ -141,35 +146,40 @@
#
# Configuration attributes for a single host network.
#
-# @vlan: #optional The name of an associated vlan
+# @vlan: #optional The name of an associated vlan
#
-# @bonding: #optional If the network is bonded, the name of the bond device
+# @bonding: #optional If the network is bonded, the name of the bond device
#
-# @nic: #optional If the network is not bonded, an array containing a
-# single network device name
+# @nic: #optional If the network is not bonded, an array containing a
+# single network device name
#
-# @ipaddr: #optional Assign this static IP address to the network
+# @ipaddr: #optional Assign this static IP address to the network
#
-# @netmask: #optional Assign this netmask to the network
+# @netmask: #optional Assign this netmask to the network
#
-# @gateway: #optional Assign this gateway to the network
+# @gateway: #optional Assign this gateway to the network
#
-# @bootproto: #optional Interface autoconfiguration protocol (typically 'dhcp'
-# or 'static')
+# @bootproto: #optional Interface autoconfiguration protocol (typically 'dhcp'
+# or 'static')
#
-# @delay: #optional The time to wait before starting the network device
+# @delay: #optional The time to wait before starting the network device
#
-# @onboot: #optional Start the network device automatically during boot
+# @onboot: #optional Start the network device automatically during boot
#
-# @remove: #optional If True, remove existing network only
+# @remove: #optional If True, remove existing network only
#
+# @qosInbound: #optional VmInterfaceDeviceBandwidthParams for incoming traffic.
+#
+# @qosOutbound: #optional VmInterfaceDeviceBandwidthParams for outgoing traffic.
+#
# Since: 4.10.0
##
{'type': 'SetupNetworkNetAttributes',
'data': {'*vlan': 'str', '*bonding': 'str', '*nic': ['str'], '*ipaddr': 'str',
'*netmask': 'str', '*gateway': 'str', '*bootproto': 'str',
- '*delay': 'uint', '*onboot': 'bool', '*remove': 'bool'}}
-
+ '*delay': 'uint', '*onboot': 'bool', '*remove': 'bool',
+ '*qosInbound': 'VmInterfaceDeviceBandwidthParams',
+ '*qosOutbound': 'VmInterfaceDeviceBandwidthParams'}}
##
# @SetupNetworkBondAttributes:
#
--
To view, visit http://gerrit.ovirt.org/15724
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: If0c3b4b9a6fd5eb53579fb2e157b5325caa88d04
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Giuseppe Vallarelli <gvallare at redhat.com>
More information about the vdsm-patches
mailing list