[Kimchi-devel] [PATCH v2] Support Linux Bridge creation
Aline Manera
alinefm at linux.vnet.ibm.com
Fri Oct 30 17:41:08 UTC 2015
On 30/10/2015 14:29, Ramon Medeiros wrote:
> 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"}'
From what I remembered from the RFC, we have agreed to do not add a new
parameter "mode" and instead of that use "connection" equal to "macvtap"
for macvtap bridge or "bridge" for Linux bridge.
Any special reason to do not follow the RFC discussion?
> 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(-)
Please, update API.json, docs/API.md and add test cases to cover the new
API.
> 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
>
> +
Just one line to separated import blocks.
> 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)
Don't you need to verify the interface is not in use by any other network?
> + 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
> +
What happen when you are not able to get a bridge name?
> + # 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):
create_linux_bridge_xml is more meaningful for this function
> + m = E.interface(
> + E.start(mode='onboot'),
> + E.bridge(
> + E.interface(
> + type='ethernet',
> + name=interface)),
> + type='bridge',
> + name=bridge)
> + return ET.tostring(m)
> +
More information about the Kimchi-devel
mailing list