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

Aline Manera alinefm at linux.vnet.ibm.com
Thu Nov 5 13:42:15 UTC 2015



On 04/11/2015 09:24, Lucio Correia wrote:
> On 30-10-2015 15:41, Aline Manera wrote:
>>
>>
>> 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?
>>
>
> Aline, could you point me to that discussion? I'm out of context here.
>
>

This is the mail thread: 
http://lists.ovirt.org/pipermail/kimchi-devel/2015-October/011981.html

>>> 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.
>>
>
> Will do.
>
>>> 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.
>>
>
> ok
>
>>>   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?
>>
>
> better to verify. Will change the elif below to an if.
>
>>> +            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?
>>
>
> I will raise a failure for that case.
>
>
>>> +        # 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
>>
>
> ok
>
>>> +    m = E.interface(
>>> +        E.start(mode='onboot'),
>>> +        E.bridge(
>>> +            E.interface(
>>> +                type='ethernet',
>>> +                name=interface)),
>>> +        type='bridge',
>>> +        name=bridge)
>>> +    return ET.tostring(m)
>>> +
>>
>> _______________________________________________
>> Kimchi-devel mailing list
>> Kimchi-devel at ovirt.org
>> http://lists.ovirt.org/mailman/listinfo/kimchi-devel
>>
>
>




More information about the Kimchi-devel mailing list