summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSoren Hansen <soren.hansen@rackspace.com>2010-10-04 20:36:46 +0200
committerSoren Hansen <soren.hansen@rackspace.com>2010-10-04 20:36:46 +0200
commit38d2e2f0e86ff2c402c4744d54ac2a3bd4367ae0 (patch)
treec6795ab712222b836e8ee50d918c961b042602f6
parent50fc372c1f4b5924b73de5c25100ce42166c4f12 (diff)
parent104940614784c69ed3d17581ff2cb1ed344eaa0f (diff)
downloadnova-38d2e2f0e86ff2c402c4744d54ac2a3bd4367ae0.tar.gz
nova-38d2e2f0e86ff2c402c4744d54ac2a3bd4367ae0.tar.xz
nova-38d2e2f0e86ff2c402c4744d54ac2a3bd4367ae0.zip
Merge trunk. Again.
-rw-r--r--nova/db/api.py11
-rw-r--r--nova/db/sqlalchemy/api.py11
-rw-r--r--nova/network/linux_net.py50
-rw-r--r--nova/network/manager.py10
-rw-r--r--nova/tests/network_unittest.py4
5 files changed, 62 insertions, 24 deletions
diff --git a/nova/db/api.py b/nova/db/api.py
index d92747dce..a6d1f405a 100644
--- a/nova/db/api.py
+++ b/nova/db/api.py
@@ -673,3 +673,14 @@ def project_update(context, project_id, values):
def project_delete(context, project_id):
"""Delete project"""
return IMPL.project_delete(context, project_id)
+
+
+###################
+
+
+def host_get_networks(context, host):
+ """Return all networks for which the given host is the designated
+ network host
+ """
+ return IMPL.host_get_networks(context, host)
+
diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py
index 49d015716..e0c6a34b8 100644
--- a/nova/db/sqlalchemy/api.py
+++ b/nova/db/sqlalchemy/api.py
@@ -240,7 +240,7 @@ def service_create(context, values):
def service_update(context, service_id, values):
session = get_session()
with session.begin():
- service_ref = session_get(context, service_id, session=session)
+ service_ref = service_get(context, service_id, session=session)
for (key, value) in values.iteritems():
service_ref[key] = value
service_ref.save(session=session)
@@ -1485,3 +1485,12 @@ def user_add_project_role(context, user_id, project_id, role):
###################
+
+
+def host_get_networks(context, host):
+ session = get_session()
+ with session.begin():
+ return session.query(models.Network
+ ).filter_by(deleted=False
+ ).filter_by(host=host
+ ).all()
diff --git a/nova/network/linux_net.py b/nova/network/linux_net.py
index 709195ba4..37f9c8253 100644
--- a/nova/network/linux_net.py
+++ b/nova/network/linux_net.py
@@ -28,6 +28,11 @@ from nova import flags
from nova import utils
+def _bin_file(script):
+ """Return the absolute path to scipt in the bin directory"""
+ return os.path.abspath(os.path.join(__file__, "../../../bin", script))
+
+
FLAGS = flags.FLAGS
flags.DEFINE_string('dhcpbridge_flagfile',
'/etc/nova/nova-dhcpbridge.conf',
@@ -38,7 +43,9 @@ flags.DEFINE_string('networks_path', utils.abspath('../networks'),
flags.DEFINE_string('public_interface', 'vlan1',
'Interface for public IP addresses')
flags.DEFINE_string('bridge_dev', 'eth0',
- 'network device for bridges')
+ 'network device for bridges')
+flags.DEFINE_string('dhcpbridge', _bin_file('nova-dhcpbridge'),
+ 'location of nova-dhcpbridge')
flags.DEFINE_string('routing_source_ip', '127.0.0.1',
'Public IP of network host')
flags.DEFINE_bool('use_nova_chains', False,
@@ -139,16 +146,16 @@ def ensure_bridge(bridge, interface, net_attrs=None):
# _execute("sudo brctl setageing %s 10" % bridge)
_execute("sudo brctl stp %s off" % bridge)
_execute("sudo brctl addif %s %s" % (bridge, interface))
- if net_attrs:
- _execute("sudo ifconfig %s %s broadcast %s netmask %s up" % \
- (bridge,
- net_attrs['gateway'],
- net_attrs['broadcast'],
- net_attrs['netmask']))
- else:
- _execute("sudo ifconfig %s up" % bridge)
- _confirm_rule("FORWARD", "--in-interface %s -j ACCEPT" % bridge)
- _confirm_rule("FORWARD", "--out-interface %s -j ACCEPT" % bridge)
+ if net_attrs:
+ _execute("sudo ifconfig %s %s broadcast %s netmask %s up" % \
+ (bridge,
+ net_attrs['gateway'],
+ net_attrs['broadcast'],
+ net_attrs['netmask']))
+ else:
+ _execute("sudo ifconfig %s up" % bridge)
+ _confirm_rule("FORWARD", "--in-interface %s -j ACCEPT" % bridge)
+ _confirm_rule("FORWARD", "--out-interface %s -j ACCEPT" % bridge)
def get_dhcp_hosts(context, network_id):
@@ -172,9 +179,14 @@ def update_dhcp(context, network_id):
signal causing it to reload, otherwise spawn a new instance
"""
network_ref = db.network_get(context, network_id)
- with open(_dhcp_file(network_ref['vlan'], 'conf'), 'w') as f:
+
+ conffile = _dhcp_file(network_ref['vlan'], 'conf')
+ with open(conffile, 'w') as f:
f.write(get_dhcp_hosts(context, network_id))
+ # Make sure dnsmasq can actually read it (it setuid()s to "nobody")
+ os.chmod(conffile, 0644)
+
pid = _dnsmasq_pid_for(network_ref['vlan'])
# if dnsmasq is already running, then tell it to reload
@@ -182,7 +194,7 @@ def update_dhcp(context, network_id):
# TODO(ja): use "/proc/%d/cmdline" % (pid) to determine if pid refers
# correct dnsmasq process
try:
- os.kill(pid, signal.SIGHUP)
+ _execute('sudo kill -HUP %d' % pid)
return
except Exception as exc: # pylint: disable-msg=W0703
logging.debug("Hupping dnsmasq threw %s", exc)
@@ -243,7 +255,7 @@ def _dnsmasq_cmd(net):
' --except-interface=lo',
' --dhcp-range=%s,static,120s' % net['dhcp_start'],
' --dhcp-hostsfile=%s' % _dhcp_file(net['vlan'], 'conf'),
- ' --dhcp-script=%s' % _bin_file('nova-dhcpbridge'),
+ ' --dhcp-script=%s' % FLAGS.dhcpbridge,
' --leasefile-ro']
return ''.join(cmd)
@@ -254,7 +266,7 @@ def _stop_dnsmasq(network):
if pid:
try:
- os.kill(pid, signal.SIGTERM)
+ _execute('sudo kill -TERM %d' % pid)
except Exception as exc: # pylint: disable-msg=W0703
logging.debug("Killing dnsmasq threw %s", exc)
@@ -262,12 +274,10 @@ def _stop_dnsmasq(network):
def _dhcp_file(vlan, kind):
"""Return path to a pid, leases or conf file for a vlan"""
- return os.path.abspath("%s/nova-%s.%s" % (FLAGS.networks_path, vlan, kind))
-
+ if not os.path.exists(FLAGS.networks_path):
+ os.makedirs(FLAGS.networks_path)
-def _bin_file(script):
- """Return the absolute path to scipt in the bin directory"""
- return os.path.abspath(os.path.join(__file__, "../../../bin", script))
+ return os.path.abspath("%s/nova-%s.%s" % (FLAGS.networks_path, vlan, kind))
def _dnsmasq_pid_for(vlan):
diff --git a/nova/network/manager.py b/nova/network/manager.py
index ef1d01138..9c1846dd9 100644
--- a/nova/network/manager.py
+++ b/nova/network/manager.py
@@ -85,6 +85,12 @@ class NetworkManager(manager.Manager):
self.driver = utils.import_object(network_driver)
super(NetworkManager, self).__init__(*args, **kwargs)
+ def init_host(self):
+ # Set up networking for the projects for which we're already
+ # the designated network host.
+ for network in self.db.host_get_networks(None, self.host):
+ self._on_set_network_host(None, network['id'])
+
def set_network_host(self, context, project_id):
"""Safely sets the host of the projects network"""
logging.debug("setting network host")
@@ -230,7 +236,7 @@ class VlanManager(NetworkManager):
now = datetime.datetime.utcnow()
timeout = FLAGS.fixed_ip_disassociate_timeout
time = now - datetime.timedelta(seconds=timeout)
- num = self.db.fixed_ip_disassociate_all_by_timeout(self,
+ num = self.db.fixed_ip_disassociate_all_by_timeout(context,
self.host,
time)
if num:
@@ -240,6 +246,7 @@ class VlanManager(NetworkManager):
"""Do any initialization that needs to be run if this is a
standalone service.
"""
+ super(VlanManager, self).init_host()
self.driver.init_host()
def allocate_fixed_ip(self, context, instance_id, *args, **kwargs):
@@ -367,6 +374,7 @@ class VlanManager(NetworkManager):
self.driver.ensure_vlan_bridge(network_ref['vlan'],
network_ref['bridge'],
network_ref)
+ self.driver.update_dhcp(context, network_id)
@property
def _bottom_reserved_ips(self):
diff --git a/nova/tests/network_unittest.py b/nova/tests/network_unittest.py
index 5370966d2..59b0a36e4 100644
--- a/nova/tests/network_unittest.py
+++ b/nova/tests/network_unittest.py
@@ -56,8 +56,8 @@ class NetworkTestCase(test.TrialTestCase):
'netuser',
name))
# create the necessary network data for the project
- user_context = context.APIRequestContext(project=self.projects[i],
- user=self.user)
+ user_context = context.get_admin_context(user=self.user)
+
self.network.set_network_host(user_context, self.projects[i].id)
instance_ref = self._create_instance(0)
self.instance_id = instance_ref['id']