summaryrefslogtreecommitdiffstats
path: root/nova
diff options
context:
space:
mode:
authorJoshua McKenty <jmckenty@joshua-mckentys-macbook-pro.local>2010-07-07 12:15:11 -0700
committerVishvananda Ishaya <vishvananda@gmail.com>2010-07-07 12:15:11 -0700
commitdbe324f7254dd3e01de44bb908150fb8397fe118 (patch)
tree7b2949e0f04402f936553622b2c84e682476ac25 /nova
parentb7ea2f70581f6acd927ea7b65adaffeeb4b8d2ba (diff)
downloadnova-dbe324f7254dd3e01de44bb908150fb8397fe118.tar.gz
nova-dbe324f7254dd3e01de44bb908150fb8397fe118.tar.xz
nova-dbe324f7254dd3e01de44bb908150fb8397fe118.zip
Got dhcpleasor working, with test ENV for testing, and rpc.cast for real world.
Diffstat (limited to 'nova')
-rw-r--r--nova/compute/linux_net.py7
-rw-r--r--nova/compute/network.py25
-rw-r--r--nova/endpoint/cloud.py8
-rw-r--r--nova/tests/network_unittest.py40
-rw-r--r--nova/utils.py2
5 files changed, 63 insertions, 19 deletions
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 """
diff --git a/nova/endpoint/cloud.py b/nova/endpoint/cloud.py
index 931c6c6e1..269fb3950 100644
--- a/nova/endpoint/cloud.py
+++ b/nova/endpoint/cloud.py
@@ -498,6 +498,14 @@ class CloudController(object):
# TODO - Strip the IP from the instance
return defer.succeed({'disassociateResponse': ["Address disassociated."]})
+ def release_ip(self, context, private_ip, **kwargs):
+ self.network.release_ip(private_ip)
+ return defer.succeed({'releaseResponse': ["Address released."]})
+
+ def lease_ip(self, context, private_ip, **kwargs):
+ self.network.lease_ip(private_ip)
+ return defer.succeed({'leaseResponse': ["Address lease."]})
+
@rbac.allow('projectmanager', 'sysadmin')
def run_instances(self, context, **kwargs):
# make sure user can access the image
diff --git a/nova/tests/network_unittest.py b/nova/tests/network_unittest.py
index 4c9f340c1..8cbc2b7cd 100644
--- a/nova/tests/network_unittest.py
+++ b/nova/tests/network_unittest.py
@@ -21,6 +21,7 @@
import os
import logging
import unittest
+import time
from nova import vendor
import IPy
@@ -86,18 +87,36 @@ class NetworkTestCase(test.TrialTestCase):
self.assertEqual(False, address in self._get_project_addresses("project0"))
def test_range_allocation(self):
+ mac = utils.generate_mac()
+ secondmac = utils.generate_mac()
+ hostname = "test-host"
address = network.allocate_ip(
- "netuser", "project0", utils.generate_mac())
+ "netuser", "project0", mac)
secondaddress = network.allocate_ip(
- "netuser", "project1", utils.generate_mac())
+ "netuser", "project1", secondmac)
+ net = network.get_project_network("project0", "default")
+ secondnet = network.get_project_network("project1", "default")
+
self.assertEqual(True,
address in self._get_project_addresses("project0"))
self.assertEqual(True,
secondaddress in self._get_project_addresses("project1"))
self.assertEqual(False, address in self._get_project_addresses("project1"))
+ # Addresses are allocated before they're issued
+ self.dnsmasq.issue_ip(mac, address, hostname, net.bridge_name)
+ self.dnsmasq.issue_ip(secondmac, secondaddress,
+ hostname, secondnet.bridge_name)
+
rv = network.deallocate_ip(address)
+ self.dnsmasq.release_ip(mac, address, hostname, net.bridge_name)
self.assertEqual(False, address in self._get_project_addresses("project0"))
+ # First address release shouldn't affect the second
+ self.assertEqual(True,
+ secondaddress in self._get_project_addresses("project1"))
+
rv = network.deallocate_ip(secondaddress)
+ self.dnsmasq.release_ip(secondmac, secondaddress,
+ hostname, secondnet.bridge_name)
self.assertEqual(False,
secondaddress in self._get_project_addresses("project1"))
@@ -127,9 +146,14 @@ class NetworkTestCase(test.TrialTestCase):
for i in range(0, 30):
name = 'toomany-project%s' % i
self.manager.create_project(name, 'netuser', name)
+ net = network.get_project_network(name, "default")
+ mac = utils.generate_mac()
+ hostname = "toomany-hosts"
address = network.allocate_ip(
- "netuser", name, utils.generate_mac())
+ "netuser", name, mac)
+ self.dnsmasq.issue_ip(mac, address, hostname, net.bridge_name)
rv = network.deallocate_ip(address)
+ self.dnsmasq.release_ip(mac, address, hostname, net.bridge_name)
self.manager.delete_project(name)
def _get_project_addresses(self, project_id):
@@ -144,15 +168,13 @@ def binpath(script):
class FakeDNSMasq(object):
def issue_ip(self, mac, ip, hostname, interface):
cmd = "%s add %s %s %s" % (binpath('dhcpleasor.py'), mac, ip, hostname)
- env = {'DNSMASQ_INTERFACE': interface, 'REDIS_DB' : '8'}
+ env = {'DNSMASQ_INTERFACE': interface, 'TESTING' : '1'}
(out, err) = utils.execute(cmd, addl_env=env)
- logging.debug(out)
- logging.debug(err)
+ logging.debug("ISSUE_IP: %s, %s " % (out, err))
def release_ip(self, mac, ip, hostname, interface):
cmd = "%s del %s %s %s" % (binpath('dhcpleasor.py'), mac, ip, hostname)
- env = {'DNSMASQ_INTERFACE': interface, 'REDIS_DB' : '8'}
+ env = {'DNSMASQ_INTERFACE': interface, 'TESTING' : '1'}
(out, err) = utils.execute(cmd, addl_env=env)
- logging.debug(out)
- logging.debug(err)
+ logging.debug("RELEASE_IP: %s, %s " % (out, err))
\ No newline at end of file
diff --git a/nova/utils.py b/nova/utils.py
index cbfdd835d..62ad00aec 100644
--- a/nova/utils.py
+++ b/nova/utils.py
@@ -48,11 +48,9 @@ def fetchfile(url, target):
execute("curl %s -o %s" % (url, target))
def execute(cmd, input=None, addl_env=None):
- #logging.debug("Running %s" % (cmd))
env = os.environ.copy()
if addl_env:
env.update(addl_env)
- logging.debug(env)
obj = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE,
stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=env)
result = None