summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRyu Ishimoto <ryu@midokura.jp>2011-07-20 06:01:11 +0900
committerRyu Ishimoto <ryu@midokura.jp>2011-07-20 06:01:11 +0900
commitf8a562edf819085820c1d6b4639f2331330cc454 (patch)
tree18e66cd81bdbfbe145f296a35ee14f0a686e0809
parentaa3df15fa304894d9e62e3282956fe406a89b136 (diff)
parent9fe72ac7b0ed0f8e294b97e267393f352c4af97f (diff)
Merged lp:~danwent/nova/network-refactoring-l2
-rw-r--r--nova/compute/manager.py18
-rw-r--r--nova/virt/libvirt/connection.py31
-rw-r--r--nova/virt/libvirt/vif.py39
-rw-r--r--nova/virt/vif.py1
-rw-r--r--nova/virt/xenapi_conn.py2
5 files changed, 71 insertions, 20 deletions
diff --git a/nova/compute/manager.py b/nova/compute/manager.py
index 960a128e0..eb52995be 100644
--- a/nova/compute/manager.py
+++ b/nova/compute/manager.py
@@ -353,7 +353,10 @@ class ComputeManager(manager.SchedulerDependentManager):
{'action_str': action_str, 'instance_id': instance_id},
context=context)
+ network_info = None
if not FLAGS.stub_network:
+ network_info = self.network_api.get_instance_nw_info(context,
+ instance)
self.network_api.deallocate_for_instance(context, instance)
volumes = instance.get('volumes') or []
@@ -365,7 +368,7 @@ class ComputeManager(manager.SchedulerDependentManager):
self.db.instance_destroy(context, instance_id)
raise exception.Error(_('trying to destroy already destroyed'
' instance: %s') % instance_id)
- self.driver.destroy(instance)
+ self.driver.destroy(instance, network_info)
if action_str == 'Terminating':
terminate_volumes(self.db, context, instance_id)
@@ -410,7 +413,9 @@ class ComputeManager(manager.SchedulerDependentManager):
self._update_state(context, instance_id, power_state.BUILDING)
- self.driver.destroy(instance_ref)
+ network_info = self.network_api.get_instance_nw_info(context,
+ instance_ref)
+ self.driver.destroy(instance_ref, network_info)
image_ref = kwargs.get('image_ref')
instance_ref.image_ref = image_ref
instance_ref.injected_files = kwargs.get('injected_files', [])
@@ -670,7 +675,10 @@ class ComputeManager(manager.SchedulerDependentManager):
"""Destroys the source instance."""
context = context.elevated()
instance_ref = self.db.instance_get(context, instance_id)
- self.driver.destroy(instance_ref)
+
+ network_info = self.network_api.get_instance_nw_info(context,
+ instance_ref)
+ self.driver.destroy(instance_ref, network_info)
usage_info = utils.usage_from_instance(instance_ref)
notifier.notify('compute.%s' % self.host,
'compute.instance.resize.confirm',
@@ -689,7 +697,9 @@ class ComputeManager(manager.SchedulerDependentManager):
instance_ref = self.db.instance_get(context, instance_id)
migration_ref = self.db.migration_get(context, migration_id)
- self.driver.destroy(instance_ref)
+ network_info = self.network_api.get_instance_nw_info(context,
+ instance_ref)
+ self.driver.destroy(instance_ref, network_info)
topic = self.db.queue_get_for(context, FLAGS.compute_topic,
instance_ref['host'])
rpc.cast(context, topic,
diff --git a/nova/virt/libvirt/connection.py b/nova/virt/libvirt/connection.py
index 85fffb14f..936e1b171 100644
--- a/nova/virt/libvirt/connection.py
+++ b/nova/virt/libvirt/connection.py
@@ -261,17 +261,13 @@ class LibvirtConnection(driver.ComputeDriver):
def setup_vif_network(self, ctxt, instance_id):
"""Set up VIF networking on the host."""
- networks = db.network_get_all_by_instance(ctxt, instance_id)
- for network in networks:
- self.vif_driver.plug(network)
-
- def destroy_vif_network(self, ctxt, instance_id):
- """Clean up VIF networking on the host."""
- networks = db.network_get_all_by_instance(ctxt, instance_id)
- for network in networks:
- self.vif_driver.unplug(network)
+ # FIXME: this is dying because DB has no networks for instances
+ #networks = db.network_get_all_by_instance(ctxt, instance_id)
+ #for network in networks:
+ # self.vif_driver.plug(network)
+ pass
- def destroy(self, instance, cleanup=True):
+ def destroy(self, instance, network_info, cleanup=True):
instance_name = instance['name']
try:
@@ -315,6 +311,14 @@ class LibvirtConnection(driver.ComputeDriver):
locals())
raise
+ try:
+ for (network, mapping) in network_info:
+ self.vif_driver.unplug(instance, network, mapping)
+ except:
+ LOG.warning("Failed while unplugging vif of instance '%s'" % \
+ instance['name'])
+ raise
+
def _wait_for_destroy():
"""Called at an interval until the VM is gone."""
instance_name = instance['name']
@@ -329,8 +333,6 @@ class LibvirtConnection(driver.ComputeDriver):
timer = utils.LoopingCall(_wait_for_destroy)
timer.start(interval=0.5, now=True)
- ctxt = context.get_admin_context()
- self.destroy_vif_network(ctxt, instance['id'])
self.firewall_driver.unfilter_instance(instance)
if cleanup:
@@ -898,9 +900,12 @@ class LibvirtConnection(driver.ComputeDriver):
address = mapping['ips'][0]['ip']
netmask = mapping['ips'][0]['netmask']
address_v6 = None
+ gateway_v6 = None
+ netmask_v6 = None
if FLAGS.use_ipv6:
address_v6 = mapping['ip6s'][0]['ip']
netmask_v6 = mapping['ip6s'][0]['netmask']
+ gateway_v6 = mapping['gateway6']
net_info = {'name': 'eth%d' % ifc_num,
'address': address,
'netmask': netmask,
@@ -908,7 +913,7 @@ class LibvirtConnection(driver.ComputeDriver):
'broadcast': mapping['broadcast'],
'dns': mapping['dns'],
'address_v6': address_v6,
- 'gateway6': mapping['gateway6'],
+ 'gateway6': gateway_v6,
'netmask_v6': netmask_v6}
nets.append(net_info)
diff --git a/nova/virt/libvirt/vif.py b/nova/virt/libvirt/vif.py
index 5974f0570..4f7bb0b4d 100644
--- a/nova/virt/libvirt/vif.py
+++ b/nova/virt/libvirt/vif.py
@@ -1,6 +1,7 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright (C) 2011 Midokura KK
+# Copyright (C) 2011 Nicira, Inc
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
@@ -20,6 +21,7 @@
from nova import flags
from nova.network import linux_net
from nova.virt.libvirt import netutils
+from nova import utils
from nova.virt.vif import VIFDriver
FLAGS = flags.FLAGS
@@ -83,7 +85,7 @@ class LibvirtBridgeDriver(VIFDriver, LibvirtBridge):
linux_net.ensure_bridge(network['bridge'],
network['bridge_interface'])
- def unplug(self, network):
+ def unplug(self, instance, network, mapping):
pass
@@ -95,5 +97,38 @@ class LibvirtVlanBridgeDriver(VIFDriver, LibvirtBridge):
linux_net.ensure_vlan_bridge(network['vlan'], network['bridge'],
network['bridge_interface'])
- def unplug(self, network):
+ def unplug(self, instance, network, mapping):
pass
+
+
+class LibvirtOpenVswitchDriver(VIFDriver):
+ """VIF driver for Open vSwitch."""
+
+ def get_configurations(self, instance, network, mapping):
+ vif_id = str(instance['id']) + "-" + str(network['id'])
+ dev = "tap-%s" % vif_id
+ utils.execute('sudo', 'ip', 'tuntap', 'add', dev, 'mode', 'tap')
+ utils.execute('sudo', 'ip', 'link', 'set', dev, 'up')
+ utils.execute('sudo', 'ovs-vsctl', '--', '--may-exist', 'add-port',
+ FLAGS.flat_network_bridge, dev,
+ '--', 'set', 'Interface', dev, "external-ids:iface-id=%s" % vif_id,
+ '--', 'set', 'Interface', dev, "external-ids:iface-status=active",
+ '--', 'set', 'Interface', dev, "external-ids:attached-mac=%s" % \
+ mapping['mac'])
+
+ result = {
+ 'script': '',
+ 'name': dev,
+ 'mac_address': mapping['mac']}
+ print "using result = %s" % str(result)
+ return result
+
+ def plug(self, network):
+ pass
+
+ def unplug(self, instance, network, mapping):
+ vif_id = str(instance['id']) + "-" + str(network['id'])
+ dev = "tap-%s" % vif_id
+ utils.execute('sudo', 'ovs-vsctl', 'del-port',
+ FLAGS.flat_network_bridge, dev)
+ utils.execute('sudo', 'ip', 'link', 'delete', dev)
diff --git a/nova/virt/vif.py b/nova/virt/vif.py
index 1ff41ed7e..bab1bdac9 100644
--- a/nova/virt/vif.py
+++ b/nova/virt/vif.py
@@ -17,6 +17,7 @@
"""VIF module common to all virt layers."""
+
class VIFDriver(object):
"""Abstract class that defines generic interfaces for all VIF drivers."""
diff --git a/nova/virt/xenapi_conn.py b/nova/virt/xenapi_conn.py
index ec8c44c1c..032ab7345 100644
--- a/nova/virt/xenapi_conn.py
+++ b/nova/virt/xenapi_conn.py
@@ -224,7 +224,7 @@ class XenAPIConnection(driver.ComputeDriver):
"""
self._vmops.inject_file(instance, b64_path, b64_contents)
- def destroy(self, instance):
+ def destroy(self, instance, network_info):
"""Destroy VM instance"""
self._vmops.destroy(instance)