
When a network interface was only visible to the system and not to libvirt, libvirt throws an error when user asks a bridged network to be created using that interface, since it is not visible to libvirt. This patch adds network interface redefinition code to make it visible to libvirt, allowing the bridged network to be created. Signed-off-by: Lucio Correia <luciojhc@linux.vnet.ibm.com> Changes in V2: - Daniel's review - Removed error message - Default interface type changed to 'network' in get_iface_xml --- src/wok/plugins/kimchi/i18n.py | 1 - src/wok/plugins/kimchi/model/networks.py | 25 ++++++++++++++++++++----- src/wok/plugins/kimchi/network.py | 5 +++++ src/wok/plugins/kimchi/xmlutils/interface.py | 20 ++++++++++++++++---- 4 files changed, 41 insertions(+), 10 deletions(-) diff --git a/src/wok/plugins/kimchi/i18n.py b/src/wok/plugins/kimchi/i18n.py index de7962a..b3414e2 100644 --- a/src/wok/plugins/kimchi/i18n.py +++ b/src/wok/plugins/kimchi/i18n.py @@ -267,7 +267,6 @@ messages = { "KCHNET0020E": _("Failed to activate interface %(iface)s: %(err)s."), "KCHNET0021E": _("Failed to activate interface %(iface)s. Please check the physical link status."), "KCHNET0022E": _("Failed to start network %(name)s. Details: %(err)s"), - "KCHNET0023E": _("Unable to get XML definition for interface %(name)s. Details: %(err)s"), "KCHNET0024E": _("Unable to redefine interface %(name)s. Details: %(err)s"), "KCHNET0025E": _("Unable to create bridge %(name)s. Details: %(err)s"), "KCHNET0026E": _("Open VSwitch bridges can only host bridged networks."), diff --git a/src/wok/plugins/kimchi/model/networks.py b/src/wok/plugins/kimchi/model/networks.py index 7f50003..403996a 100644 --- a/src/wok/plugins/kimchi/model/networks.py +++ b/src/wok/plugins/kimchi/model/networks.py @@ -33,6 +33,7 @@ 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.interface import get_iface_xml from wok.plugins.kimchi.xmlutils.network import create_linux_bridge_xml from wok.plugins.kimchi.xmlutils.network import create_vlan_tagged_bridge_xml from wok.plugins.kimchi.xmlutils.network import get_no_network_config_xml @@ -240,13 +241,29 @@ class NetworksModel(object): # get xml definition of interface iface_xml = self._get_interface_desc_xml(interface) + # interface not defined in libvirt: try to define it + iface_defined = False + conn = self.conn.get() + if iface_xml is None: + try: + mac = knetwork.get_dev_macaddr(str(interface)) + iface_xml = get_iface_xml({'type': 'ethernet', + 'name': interface, + 'mac': mac, + 'startmode': "onboot"}) + conn.interfaceDefineXML(iface_xml.encode("utf-8")) + iface_defined = True + except libvirt.libvirtError, e: + raise OperationFailed("KCHNET0024E", {'name': interface, + 'err': e.get_error_message()}) + # Truncate the interface name if it exceeds 13 characters to make sure # the length of bridge name is less than 15 (its maximum value). br_name = KIMCHI_BRIDGE_PREFIX + interface[-13:] br_xml = create_linux_bridge_xml(br_name, interface, iface_xml) # drop network config from interface - self._redefine_iface_no_network(interface) + iface_defined or self._redefine_iface_no_network(interface, iface_xml) # create and start bridge self._create_bridge(br_name, br_xml) @@ -270,16 +287,14 @@ class NetworksModel(object): iface = conn.interfaceLookupByName(name) xml = iface.XMLDesc(flags=VIR_INTERFACE_XML_INACTIVE) except libvirt.libvirtError, e: - raise OperationFailed("KCHNET0023E", - {'name': name, 'err': e.get_error_message()}) + return None return xml - def _redefine_iface_no_network(self, name): + def _redefine_iface_no_network(self, name, iface_xml): conn = self.conn.get() # drop network config from definition of interface - iface_xml = self._get_interface_desc_xml(name) xml = get_no_network_config_xml(iface_xml.encode("utf-8")) try: diff --git a/src/wok/plugins/kimchi/network.py b/src/wok/plugins/kimchi/network.py index 1433b8a..eee0e8c 100644 --- a/src/wok/plugins/kimchi/network.py +++ b/src/wok/plugins/kimchi/network.py @@ -31,6 +31,11 @@ DefaultNetsPool = [ipaddr.IPNetwork('192.168.122.0/23'), ipaddr.IPNetwork('192.168.128.0/17')] +def get_dev_macaddr(dev): + info = ethtool.get_interfaces_info(dev)[0] + return info.mac_address + + def get_dev_netaddr(dev): info = ethtool.get_interfaces_info(dev)[0] return (info.ipv4_address and diff --git a/src/wok/plugins/kimchi/xmlutils/interface.py b/src/wok/plugins/kimchi/xmlutils/interface.py index 64df8cd..814caf9 100644 --- a/src/wok/plugins/kimchi/xmlutils/interface.py +++ b/src/wok/plugins/kimchi/xmlutils/interface.py @@ -26,15 +26,27 @@ from wok.plugins.kimchi import osinfo def get_iface_xml(params, arch=None, os_distro=None, os_version=None): """ - <interface type='network'> + <interface type='network' name='ethX'> + <start mode='onboot'/> <source network='default'/> <model type='virtio'/> </interface> """ - interface = E.interface(type=params['type']) - interface.append(E.source(network=params['network'])) + name = params.get('name', None) + if name: + interface = E.interface(type=params.get('type', 'network'), name=name) + else: + interface = E.interface(type=params.get('type', 'network')) - model = params.get('model') + stmode = params.get('startmode', None) + if stmode: + interface.append(E.start(mode=stmode)) + + nw = params.get('network', None) + if nw: + interface.append(E.source(network=nw)) + + model = params.get('model', None) # no model specified; let's try querying osinfo if model is None: -- 1.9.1