[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