Set network bridge names manually

- libvirt bridge name generator allows to create only 256 names
  so this patch returns some logic for manual generation of
  bridge names.
- Node network interface names are still generated by libvirt
  (and limited to 65536 names)

Change-Id: Ife31acd300466f660f7525e8f4fd6927ae1e2158
Related-Bug: #1590419
Implements: blueprint fuel-devops-multiple-databases
This commit is contained in:
Anton Studenov 2016-07-08 23:42:34 +03:00
parent 0099af9c7d
commit 1955f25c4b
3 changed files with 51 additions and 4 deletions

View File

@ -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

View File

@ -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:

View File

@ -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(
'<name>{0}_{1}</name>'
''.format(self.net.environment.name, self.net.name),
xml)
self.assertXMLIn('<bridge delay="0" stp="on" />', xml)
self.assertXMLIn('<bridge delay="0" name="fuelbr0" stp="on" />', xml)
self.driver_mock.get_available_device_name.assert_called_once_with(
'fuelbr')
def test_forward(self):
self.net.forward = "nat"