humble devassy has uploaded a new change for review.
Change subject: hooks: macbind - This hook support binding specified mac address to custom/other bridge than the currently defined bridge in ovirt. This hook is also capable of binding a mac address to openvswitch bridge. ......................................................................
hooks: macbind - This hook support binding specified mac address to custom/other bridge than the currently defined bridge in ovirt. This hook is also capable of binding a mac address to openvswitch bridge.
Change-Id: I0356dfab224a9082b44aae1c66df050f7456301c Signed-off-by: Humble Chirammal hchiramm@redhat.com --- A vdsm_hooks/macbind/Makefile.am A vdsm_hooks/macbind/README A vdsm_hooks/macbind/before_vm_start.py 3 files changed, 187 insertions(+), 0 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/95/17895/1
diff --git a/vdsm_hooks/macbind/Makefile.am b/vdsm_hooks/macbind/Makefile.am new file mode 100644 index 0000000..27dc5af --- /dev/null +++ b/vdsm_hooks/macbind/Makefile.am @@ -0,0 +1,30 @@ +# +# 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 = \ + before_vm_start.py + +install-data-local: + $(MKDIR_P) $(DESTDIR)$(vdsmhooksdir)/before_vm_start + $(INSTALL_SCRIPT) $(srcdir)/before_vm_start.py \ + $(DESTDIR)$(vdsmhooksdir)/before_vm_start/50_macbind + +uninstall-local: + $(RM) $(DESTDIR)$(vdsmhooksdir)/before_vm_start/50_macbind diff --git a/vdsm_hooks/macbind/README b/vdsm_hooks/macbind/README new file mode 100644 index 0000000..15bcfeb --- /dev/null +++ b/vdsm_hooks/macbind/README @@ -0,0 +1,39 @@ +macbind vdsm hook: +============ +This hook goes through all of the VM's interfaces and manipulate its +XML file acccording to the input. This can be used to attach a VM nic +to a specific bridge which is available in the hypervisor for 'that' VM run +or permanently. + + +One specific use case being attach a virtual network interface to an +openvswitch bridge. Other being, attach vm nic to a different bridge +than the defined/default bridge for that NIC. + + +Syntax: + macbind=macaddress-brName-portType,... + +where: + +macaddress: specify a macaddress which need to be attached to the VM +brName : Bridge Name available in hypervisor +portType : This have to either 'ovs' or 'lb' or '' + +For ex: + +macbind= 00:1a:4a:41:d2:5f-ovsbr0-ovs,00:1a:4a:41:d2:b8-br88-lb + +Installation: +* Use the engine-config to append the appropriate custom property as such: + sudo engine-config -s UserDefinedVMProperties= + 'previousProperties;macbind=^.*$' --cver=3.2 + +* Verify that the macbind custom property was properly added: + sudo engine-config -g UserDefinedVMProperties + +Usage: +In the VM configuration window, open the custom properites tab +and add macbind= + +NOTE: Live migration is **not** tested. diff --git a/vdsm_hooks/macbind/before_vm_start.py b/vdsm_hooks/macbind/before_vm_start.py new file mode 100755 index 0000000..5606614 --- /dev/null +++ b/vdsm_hooks/macbind/before_vm_start.py @@ -0,0 +1,118 @@ +#!/usr/bin/python + +import os +import sys +import hooking +import traceback + +''' + +macbind: + +syntax: +macbind=macaddress-brName-portType,... +refer README for more details. + + +if 'ovs' as portType: + +<interface type='bridge'> + <mac address='00:1a:4a:41:d2:5f'/> + <source bridge='ovsbr0'/> + <model type='virtio'/> + <virtualport type='openvswitch'/> + <filterref filter='vdsm-no-mac-spoofing'/> + <link state='up'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/> +</interface> + +If 'lb' or '' as portType: +The given bridge will be replaced with current bridge: + +<interface type='bridge'> + <mac address='00:1a:4a:41:d2:b8'/> + <source bridge='br0'/> + <model type='virtio'/> + <filterref filter='vdsm-no-mac-spoofing'/> + <link state='up'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/> +</interface> + +''' + + +def createVportElement(domxml, porttype): + vPort = domxml.createElement('virtualport') + vPort.setAttribute('type', 'openvswitch') + return vPort + + +def createSbridgeElement(domxml, brName): + sBridge = domxml.createElement('source') + sBridge.setAttribute('bridge', brName) + return sBridge + + +def removeElement(interface, Element): + interface.removeChild(Element) + + +if 'macbind' in os.environ: + try: + + macbinds = os.environ['macbind'] + domxml = hooking.read_domxml() + macAddr = '' + brName = '' + pType = '' + + for nic in macbinds.split(','): + try: + macAddr, brName, pType = nic.split('-') + macAddr = macAddr.strip() + brName = brName.strip() + pType = pType.strip() + + except ValueError: + sys.stderr.write('macbind: input error, expected ' + 'macbind:macAddr:brName:pType,' + 'where brName is bridgename' + 'pType can be ovs|lb') + sys.exit(2) + if pType == "ovs": + command = ['/usr/bin/ovs-vsctl', 'br-exists %s' % (brName)] + retcode, out, err = hooking.execCmd( + command, sudo=False, raw=True) + if retcode != 0: + sys.stderr.write('macbind: Error in finding ovsbridge:' + '%s: %s, err = %s' % + (brName, ' '.join(command), err)) + continue + if pType == "lb" or pType == '': + command = ['/usr/sbin/brctl', 'show', brName] + retcode, out, err = hooking.execCmd( + command, sudo=False, raw=True) + + if err or retcode != 0: + sys.stderr.write('macbind: Error in finding Linuxbridge:' + ' %s \n: %s, err = %s\n' % + (brName, ' '.join(command), err)) + continue + + for interface in domxml.getElementsByTagName('interface'): + for macaddress in interface.getElementsByTagName('mac'): + addr = macaddress.getAttribute('address') + if addr == macAddr: + for bridge in interface.getElementsByTagName('source'): + interface.removeChild(bridge) + interface.appendChild( + createSbridgeElement(domxml, brName)) + if pType == "ovs": + interface.appendChild( + createVportElement(domxml, 'openvswitch')) + + hooking.write_domxml(domxml) + except: + sys.stderr.write('macbind: [unexpected error]: %s\n' % + traceback.format_exc()) + sys.exit(2)