[Kimchi-devel] [PATCH v2] Support Linux Bridge creation

Ramon Medeiros ramonn at linux.vnet.ibm.com
Fri Oct 30 16:29:49 UTC 2015


Create linux-bridge with libvirt API. Kimchi was only creating macvtap
devices, with has some limitation. For further information, take a look
at Kimchi wiki discuss:
https://github.com/kimchi-project/kimchi/wiki/Create-guest-network

Signed-off-by: Ramon Medeiros <ramonn at linux.vnet.ibm.com>

Changes:

v2: 

Remove unused imports and constants
Fix pep8 issues


Testing:

In my case, i create a new bridge over the interface enp0s25 with name ramon

curl -u root  -H "Content-Type: application/json" -H "Accept: application/json" "http://localhost:8010/plugins/kimchi/networks" -X POST -d '{"name": "ramon", "connection":"bridge", "interface":"enp0s25", "mode":"linux-bridge"}'

To delete, you can remove by UI or:

curl -u root  -H "Content-Type: application/json" -H "Accept: application/json" "http://localhost:8010/plugins/kimchi/networks/ramon" -X DELETE -d ''

---
 src/wok/plugins/kimchi/model/networks.py   | 35 ++++++++++++++++++++++++++++--
 src/wok/plugins/kimchi/network.py          | 19 ++++++++++++++++
 src/wok/plugins/kimchi/xmlutils/network.py | 12 ++++++++++
 3 files changed, 64 insertions(+), 2 deletions(-)

diff --git a/src/wok/plugins/kimchi/model/networks.py b/src/wok/plugins/kimchi/model/networks.py
index 71ea595..c17a3bf 100644
--- a/src/wok/plugins/kimchi/model/networks.py
+++ b/src/wok/plugins/kimchi/model/networks.py
@@ -30,12 +30,13 @@ from wok.rollbackcontext import RollbackContext
 from wok.utils import run_command, wok_log
 from wok.xmlutils.utils import xpath_get_text
 
+
 from wok.plugins.kimchi import netinfo
 from wok.plugins.kimchi import network as knetwork
 from wok.plugins.kimchi.osinfo import defaults as tmpl_defaults
 from wok.plugins.kimchi.xmlutils.network import create_vlan_tagged_bridge_xml
 from wok.plugins.kimchi.xmlutils.network import to_network_xml
-
+from wok.plugins.kimchi.xmlutils.network import create_linux_bridge
 
 KIMCHI_BRIDGE_PREFIX = 'kb'
 
@@ -160,7 +161,10 @@ class NetworksModel(object):
     def _set_network_bridge(self, params):
         try:
             iface = params['interface']
-            if iface in self.get_all_networks_interfaces():
+
+            if params["mode"] == "linux-bridge":
+                iface = self._create_linux_bridge(iface)
+            elif iface in self.get_all_networks_interfaces():
                 msg_args = {'iface': iface, 'network': params['name']}
                 raise InvalidParameter("KCHNET0006E", msg_args)
         except KeyError:
@@ -196,6 +200,33 @@ class NetworksModel(object):
             net_dict['bridge'] and interfaces.append(net_dict['bridge'])
         return interfaces
 
+    def _create_linux_bridge(self, interface):
+        newBridge = KIMCHI_BRIDGE_PREFIX + interface[-8:]
+        bridges_list = knetwork.list_bridges()
+
+        bridges = []
+        for bridge in bridges_list:
+            bridges.append(bridge["bridge"])
+
+        # bridge already exists: create new name
+        if newBridge in bridges:
+            for i in range(0, 10):
+                newBridge = KIMCHI_BRIDGE_PREFIX + interface[-7:] + str(i)
+                if newBridge not in bridges:
+                        break
+
+        # create linux bridge by libvirt
+        try:
+            conn = self.conn.get()
+            iface = conn.interfaceDefineXML(create_linux_bridge(newBridge,
+                                                                interface))
+            iface.create()
+        except libvirt.libvirtError as e:
+            raise OperationFailed("KCHNET0008E",
+                                  {'name': newBridge,
+                                   'err': e.get_error_message()})
+        return newBridge
+
     def _create_vlan_tagged_bridge(self, interface, vlan_id):
         # Truncate the interface name if it exceeds 8 characters to make sure
         # the length of bridge name is less than 15 (its maximum value).
diff --git a/src/wok/plugins/kimchi/network.py b/src/wok/plugins/kimchi/network.py
index 1433b8a..18df281 100644
--- a/src/wok/plugins/kimchi/network.py
+++ b/src/wok/plugins/kimchi/network.py
@@ -21,6 +21,7 @@
 import ethtool
 import ipaddr
 
+from wok.utils import run_command
 
 APrivateNets = ipaddr.IPNetwork("10.0.0.0/8")
 BPrivateNets = ipaddr.IPNetwork("172.16.0.0/12")
@@ -60,3 +61,21 @@ def get_one_free_network(used_nets, nets_pool=PrivateNets):
         if net:
             return net
     return None
+
+def list_bridges():
+    # get all bridges
+    _, err, rc = run_command(['brctl', 'show'])
+    output = _.splitlines()
+
+    # iterate over output
+    i = 1
+    bridges = []
+    while (i < len(output)):
+
+        # get bridge name
+        bridges.append({"bridge": output[i].split('\t')[0],
+                        "interface": output[i].split('\t')[5]})
+        i += 1
+
+    return bridges
+
diff --git a/src/wok/plugins/kimchi/xmlutils/network.py b/src/wok/plugins/kimchi/xmlutils/network.py
index c73aad9..2fdf8d4 100644
--- a/src/wok/plugins/kimchi/xmlutils/network.py
+++ b/src/wok/plugins/kimchi/xmlutils/network.py
@@ -120,3 +120,15 @@ def create_vlan_tagged_bridge_xml(bridge, interface, vlan_id):
         type='bridge',
         name=bridge)
     return ET.tostring(m)
+
+def create_linux_bridge(bridge, interface):
+    m = E.interface(
+        E.start(mode='onboot'),
+        E.bridge(
+            E.interface(
+                type='ethernet',
+                name=interface)),
+        type='bridge',
+        name=bridge)
+    return ET.tostring(m)
+
-- 
2.1.0




More information about the Kimchi-devel mailing list