From 37fed00260b665f175598e6da108542c0c641401 Mon Sep 17 00:00:00 2001 From: vic Date: Mon, 17 Sep 2012 16:45:49 +0400 Subject: [PATCH] Fix ip allocation --- devops/devops/controller.py | 39 ++++++++++++++++++--------------- devops/devops/driver/libvirt.py | 14 ++++++------ devops/devops/model.py | 8 ++++++- 3 files changed, 35 insertions(+), 26 deletions(-) diff --git a/devops/devops/controller.py b/devops/devops/controller.py index 743475fff..b161d0710 100644 --- a/devops/devops/controller.py +++ b/devops/devops/controller.py @@ -56,6 +56,7 @@ class Controller: for interface in node.interfaces: interface.node = node interface.network.interfaces.append(interface) + logger.info("Calculated interfaces '%s' '%s'" % (interface.node, interface.network.name)) for disk in node.disks: if disk.base_image and disk.base_image.find('://') != -1: @@ -84,27 +85,23 @@ class Controller: for address in interface.ip_addresses: if address in network.ip_addresses: allocated_addresses.append(address) - - next_address_index = 2 + logger.info("Allocate addresses are calculated for '%s'" % network.name) + dhcp_allowed_addresses = list(network.ip_addresses)[2:-2] for interface in network.interfaces: - if not len(interface.ip_addresses): - while next_address_index < network.ip_addresses.numhosts and\ - network.ip_addresses[ - next_address_index] in allocated_addresses: - next_address_index += 1 - - if next_address_index >= network.ip_addresses.numhosts: - raise DevopsError, "Failed to allocated IP address for node '%s' in network '%s': no more addresses left" % (node.name, network.name) - - address = network.ip_addresses[next_address_index] + logger.info("Enumerated interfaces '%s' '%s'" % (interface.node, interface.network.name)) + logger.info(list(interface.ip_addresses)) + if not len(list(interface.ip_addresses)): + address = self.get_first_free_address( + dhcp_allowed_addresses, + allocated_addresses) + if address is None: + raise DevopsError, "Failed to allocate IP address for node '%s' in network '%s': no more addresses left" % (interface.node.name, network.name) interface.ip_addresses.append(address) - allocated_addresses.append(next_address_index) - next_address_index += 1 + logger.info("Allocate IP address '%s' for node '%s' in network '%s'" % (address, interface.node.name, network.name)) + allocated_addresses.append(address) - network.dhcp_dynamic_address_start = network.ip_addresses[ - next_address_index] - network.dhcp_dynamic_address_end = network.ip_addresses[ - network.ip_addresses.numhosts - 2] + network.dhcp_dynamic_address_start = dhcp_allowed_addresses[0] + network.dhcp_dynamic_address_end = dhcp_allowed_addresses[-1] for network in environment.networks: logger.info("Building network %s" % network.name) @@ -303,3 +300,9 @@ class Controller: return cached_path + def get_first_free_address(self, allowed_addresses, allocated_addresses): + s = set(allocated_addresses) + for x in allowed_addresses: + if x not in s: + return x + return None diff --git a/devops/devops/driver/libvirt.py b/devops/devops/driver/libvirt.py index 9ca8ce91d..287393eda 100644 --- a/devops/devops/driver/libvirt.py +++ b/devops/devops/driver/libvirt.py @@ -70,11 +70,11 @@ class LibvirtXMLBuilder: else: end = network.ip_addresses[ network.ip_addresses.numhosts - 2] - + allowed_addresses = list(network.ip_addresses)[2: network.ip_addresses.numhosts - 2] network_xml.range(start=str(start), end=str(end)) for interface in network.interfaces: address = find( - lambda ip: ip in network.ip_addresses, + lambda ip: ip in allowed_addresses, interface.ip_addresses) if address and interface.mac_address: network_xml.host( @@ -282,11 +282,12 @@ class Libvirt: process.wait() if process.returncode: logger.error( - "Command '%s' returned %d, stderr: %s" % ( - command, process.returncode, process.stderr.read())) + "Command '{0:>s}' returned {1:d}, stderr: {2:>s}".format( + command, process.returncode, process.stderr.read())) else: logger.debug( - "Command '%s' returned %d" % (command, process.returncode)) + "Command '{0:>s}' returned {1:d}".format(command, + process.returncode)) snapshot_ids = [] for line in process.stdout.readlines()[2:]: @@ -389,8 +390,7 @@ class Libvirt: process.wait() if process.returncode: logger.error( - "Command '%s' returned code %d:\n%s" % ( - command, + "Command '{0:>s}' returned code {1:d}:\n{2:>s}".format(command, process.returncode, process.stderr.read())) raise LibvirtException, "Failed to execute command '%s'" % command diff --git a/devops/devops/model.py b/devops/devops/model.py index fcdc25677..a67077787 100644 --- a/devops/devops/model.py +++ b/devops/devops/model.py @@ -1,10 +1,15 @@ from itertools import chain +class EnvironmentException(object): + pass + + class ManagedObject(object): def __init__(self): super(ManagedObject, self).__init__() self._driver = None + self.name = None @property def driver(self): @@ -154,7 +159,8 @@ class Disk(object): class Interface(ManagedObject): - def __init__(self, network, ip_addresses=[]): + def __init__(self, network, ip_addresses=None): + if not ip_addresses: ip_addresses = [] self.node = None self.network = network if not isinstance(ip_addresses, (list, tuple)):