diff --git a/devops/driver/libvirt/libvirt_driver.py b/devops/driver/libvirt/libvirt_driver.py
index 3ab3c952..fe10fefc 100644
--- a/devops/driver/libvirt/libvirt_driver.py
+++ b/devops/driver/libvirt/libvirt_driver.py
@@ -14,6 +14,7 @@
from __future__ import division
import datetime
+import itertools
import os
from time import sleep
import xml.etree.ElementTree as ET
@@ -121,6 +122,8 @@ class Snapshot(object):
class DevopsDriver(object):
+ _device_name_generators = {}
+
def __init__(self,
connection_string="qemu:///system",
storage_pool_name="default",
@@ -274,7 +277,7 @@ class DevopsDriver(object):
else:
raise
- @retry()
+ @retry(delay=3)
def network_define(self, network):
"""Define network
@@ -1071,3 +1074,42 @@ class DevopsDriver(object):
else:
logger.warning("Can't close tray: no cdrom devices "
"found for Node {!r}".format(node.name))
+
+ def get_allocated_device_names(self):
+ """Get list of existing bridge names and network devices
+
+ :rtype : List
+ """
+ names = []
+
+ # Local Network Devices
+ for dev in self.conn.listAllDevices():
+ xml = ET.fromstring(dev.XMLDesc())
+ name_el = xml.find('./capability/interface')
+ if name_el is None:
+ continue
+ name = name_el.text
+ names.append(name)
+
+ # Network Bridges
+ for net in self.conn.listAllNetworks():
+ names.append(net.bridgeName())
+
+ return names
+
+ def get_available_device_name(self, prefix):
+ """Get available name for bridge
+
+ :type prefix: str
+ :rtype : String
+ """
+ allocated_names = self.get_allocated_device_names()
+ if prefix not in self._device_name_generators:
+ self._device_name_generators[prefix] = (
+ '{}{}'.format(prefix, i) for i in itertools.count())
+ all_names = self._device_name_generators[prefix]
+
+ for name in all_names:
+ if name in allocated_names:
+ continue
+ return name
diff --git a/devops/driver/libvirt/libvirt_xml_builder.py b/devops/driver/libvirt/libvirt_xml_builder.py
index ac0b6007..b8d64782 100644
--- a/devops/driver/libvirt/libvirt_xml_builder.py
+++ b/devops/driver/libvirt/libvirt_xml_builder.py
@@ -51,8 +51,9 @@ class LibvirtXMLBuilder(object):
stp_val = 'off'
if self.driver.stp:
stp_val = 'on'
- # bridge_name will be generated by libvirt with prefix 'virbr'
+
network_xml.bridge(
+ name=self.driver.get_available_device_name(br_prefix),
stp=stp_val, delay="0")
if network.forward is not None:
diff --git a/devops/tests/test_libvirt_xml_builder.py b/devops/tests/test_libvirt_xml_builder.py
index 48ba637e..39f18445 100644
--- a/devops/tests/test_libvirt_xml_builder.py
+++ b/devops/tests/test_libvirt_xml_builder.py
@@ -28,7 +28,8 @@ class BaseTestXMLBuilder(TestCase):
def setUp(self):
# TODO(prmtl): make it fuzzy
self.volume_path = "volume_path_mock"
- self.xml_builder = LibvirtXMLBuilder(mock.Mock())
+ self.driver_mock = mock.Mock()
+ self.xml_builder = LibvirtXMLBuilder(self.driver_mock)
self.xml_builder.driver.volume_path = mock.Mock(
return_value=self.volume_path
)
@@ -104,12 +105,15 @@ class TestNetworkXml(BaseTestXMLBuilder):
self.net.has_dhcp_server = False
def test_net_name_bridge_name(self):
+ self.driver_mock.get_available_device_name.return_value = 'fuelbr0'
xml = self.xml_builder.build_network_xml(self.net)
self.assertXMLIn(
'{0}_{1}'
''.format(self.net.environment.name, self.net.name),
xml)
- self.assertXMLIn('', xml)
+ self.assertXMLIn('', xml)
+ self.driver_mock.get_available_device_name.assert_called_once_with(
+ 'fuelbr')
def test_forward(self):
self.net.forward = "nat"