From b7ea2f70581f6acd927ea7b65adaffeeb4b8d2ba Mon Sep 17 00:00:00 2001 From: Joshua McKenty Date: Wed, 7 Jul 2010 12:06:34 -0700 Subject: Capture signals from dnsmasq and use them to update network state. --- nova/compute/linux_net.py | 9 ++++++++- nova/compute/network.py | 14 +++++++++++--- 2 files changed, 19 insertions(+), 4 deletions(-) (limited to 'nova/compute') diff --git a/nova/compute/linux_net.py b/nova/compute/linux_net.py index 0bd5ce007..b44cf9437 100644 --- a/nova/compute/linux_net.py +++ b/nova/compute/linux_net.py @@ -62,6 +62,9 @@ def remove_rule(cmd): def bind_public_ip(ip, interface): runthis("Binding IP to interface: %s", "sudo ip addr add %s dev %s" % (ip, interface)) + +def unbind_public_ip(ip, interface): + runthis("Binding IP to interface: %s", "sudo ip addr del %s dev %s" % (ip, interface)) def vlan_create(net): """ create a vlan on on a bridge device unless vlan already exists """ @@ -98,7 +101,8 @@ def dnsmasq_cmd(net): ' --dhcp-range=%s,static,120s' % (net.dhcp_range_start), ' --dhcp-lease-max=61', ' --dhcp-hostsfile=%s' % dhcp_file(net['vlan'], 'conf'), - ' --dhcp-leasefile=%s' % dhcp_file(net['vlan'], 'leases')] + ' --dhcp-leasefile=%s' % dhcp_file(net['vlan'], 'leases'), + ' ---dhcp-script=%s' % bin_file('dhcpleasor.py')] return ''.join(cmd) def hostDHCP(network, host, mac): @@ -154,6 +158,9 @@ def dhcp_file(vlan, kind): return os.path.abspath("%s/nova-%s.%s" % (FLAGS.networks_path, vlan, kind)) +def bin_file(script): + return os.path.abspath(os.path.join(__file__, "../../../bin", script)) + def dnsmasq_pid_for(network): """ the pid for prior dnsmasq instance for a vlan, returns None if no pid file exists diff --git a/nova/compute/network.py b/nova/compute/network.py index 911d0344a..7a347aa11 100644 --- a/nova/compute/network.py +++ b/nova/compute/network.py @@ -162,12 +162,16 @@ class BaseNetwork(datastore.RedisModel): return address raise exception.NoMoreAddresses() - def deallocate_ip(self, ip_str): + def release_ip(self, ip_str): if not ip_str in self.assigned: raise exception.AddressNotAllocated() self.deexpress(address=ip_str) self._rem_host(ip_str) + def deallocate_ip(self, ip_str): + # Do nothing for now, cleanup on ip release + pass + def list_addresses(self): for address in self.hosts: yield address @@ -197,7 +201,7 @@ class BridgedNetwork(BaseNetwork): def get_network_for_project(cls, user_id, project_id, security_group): vlan = get_vlan_for_project(project_id) network_str = get_subnet_from_vlan(vlan) - logging.debug("creating network on vlan %s with network string %s" % (vlan, network_str)) + # logging.debug("creating network on vlan %s with network string %s" % (vlan, network_str)) return cls.create(user_id, project_id, security_group, vlan, network_str) def __init__(self, *args, **kwargs): @@ -221,7 +225,7 @@ class DHCPNetwork(BridgedNetwork): def __init__(self, *args, **kwargs): super(DHCPNetwork, self).__init__(*args, **kwargs) - logging.debug("Initing DHCPNetwork object...") + # logging.debug("Initing DHCPNetwork object...") self.dhcp_listen_address = self.network[1] self.dhcp_range_start = self.network[3] self.dhcp_range_end = self.network[-(1 + FLAGS.cnt_vpn_clients)] @@ -372,6 +376,7 @@ class PublicNetworkController(BaseNetwork): def deexpress(self, address=None): addr = self.get_host(address) private_ip = addr['private_ip'] + linux_net.unbind_public_ip(address, FLAGS.public_interface) linux_net.remove_rule("PREROUTING -t nat -d %s -j DNAT --to %s" % (address, private_ip)) linux_net.remove_rule("POSTROUTING -t nat -s %s -j SNAT --to %s" @@ -416,8 +421,11 @@ def get_vlan_for_project(project_id): def get_network_by_address(address): + logging.debug("Get Network By Address:") for project in users.UserManager.instance().get_projects(): + logging.debug(" looking at project %s", project.id) net = get_project_network(project.id) + logging.debug(" is %s in %s ?" % (address, str(net.assigned))) if address in net.assigned: return net raise exception.AddressNotAllocated() -- cgit From dbe324f7254dd3e01de44bb908150fb8397fe118 Mon Sep 17 00:00:00 2001 From: Joshua McKenty Date: Wed, 7 Jul 2010 12:15:11 -0700 Subject: Got dhcpleasor working, with test ENV for testing, and rpc.cast for real world. --- nova/compute/linux_net.py | 7 +++---- nova/compute/network.py | 25 +++++++++++++++++++++---- 2 files changed, 24 insertions(+), 8 deletions(-) (limited to 'nova/compute') diff --git a/nova/compute/linux_net.py b/nova/compute/linux_net.py index b44cf9437..c9e5bb1a7 100644 --- a/nova/compute/linux_net.py +++ b/nova/compute/linux_net.py @@ -98,11 +98,10 @@ def dnsmasq_cmd(net): ' --pid-file=%s' % dhcp_file(net['vlan'], 'pid'), ' --listen-address=%s' % net.dhcp_listen_address, ' --except-interface=lo', - ' --dhcp-range=%s,static,120s' % (net.dhcp_range_start), - ' --dhcp-lease-max=61', + ' --dhcp-range=%s,static,600s' % (net.dhcp_range_start), ' --dhcp-hostsfile=%s' % dhcp_file(net['vlan'], 'conf'), - ' --dhcp-leasefile=%s' % dhcp_file(net['vlan'], 'leases'), - ' ---dhcp-script=%s' % bin_file('dhcpleasor.py')] + ' --dhcp-script=%s' % bin_file('dhcpleasor.py'), + ' --leasefile-ro'] return ''.join(cmd) def hostDHCP(network, host, mac): diff --git a/nova/compute/network.py b/nova/compute/network.py index 7a347aa11..96b8e9627 100644 --- a/nova/compute/network.py +++ b/nova/compute/network.py @@ -160,7 +160,10 @@ class BaseNetwork(datastore.RedisModel): self._add_host(user_id, project_id, address, mac) self.express(address=address) return address - raise exception.NoMoreAddresses() + raise exception.NoMoreAddresses("Project %s with network %s" % (project_id, str(self.network))) + + def lease_ip(self, ip_str): + logging.debug("Leasing allocated IP %s" % (ip_str)) def release_ip(self, ip_str): if not ip_str in self.assigned: @@ -419,14 +422,22 @@ def get_vlan_for_project(project_id): return vlan raise exception.AddressNotAllocated("Out of VLANs") +def get_project_id_for_vlan(vlan): + assigned_vlans = get_assigned_vlans() + for project_id, project_vlan in assigned_vlans.iteritems(): + if vlan == project_vlan: + return project_id + +def get_network_by_interface(iface, security_group='default'): + vlan = iface.rpartition("br")[2] + return get_project_network(get_project_id_for_vlan(vlan), security_group) def get_network_by_address(address): - logging.debug("Get Network By Address:") + logging.debug("Get Network By Address: %s" % address) for project in users.UserManager.instance().get_projects(): - logging.debug(" looking at project %s", project.id) net = get_project_network(project.id) - logging.debug(" is %s in %s ?" % (address, str(net.assigned))) if address in net.assigned: + logging.debug("Found %s in %s" % (address, project.id)) return net raise exception.AddressNotAllocated() @@ -438,6 +449,12 @@ def allocate_ip(user_id, project_id, mac): def deallocate_ip(address): return get_network_by_address(address).deallocate_ip(address) + +def release_ip(address): + return get_network_by_address(address).release_ip(address) + +def lease_ip(address): + return get_network_by_address(address).lease_ip(address) def get_project_network(project_id, security_group='default'): """ get a project's private network, allocating one if needed """ -- cgit