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(a)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