diff options
| author | Ryu Ishimoto <ryu@midokura.jp> | 2011-07-20 06:01:11 +0900 |
|---|---|---|
| committer | Ryu Ishimoto <ryu@midokura.jp> | 2011-07-20 06:01:11 +0900 |
| commit | f8a562edf819085820c1d6b4639f2331330cc454 (patch) | |
| tree | 18e66cd81bdbfbe145f296a35ee14f0a686e0809 | |
| parent | aa3df15fa304894d9e62e3282956fe406a89b136 (diff) | |
| parent | 9fe72ac7b0ed0f8e294b97e267393f352c4af97f (diff) | |
Merged lp:~danwent/nova/network-refactoring-l2
| -rw-r--r-- | nova/compute/manager.py | 18 | ||||
| -rw-r--r-- | nova/virt/libvirt/connection.py | 31 | ||||
| -rw-r--r-- | nova/virt/libvirt/vif.py | 39 | ||||
| -rw-r--r-- | nova/virt/vif.py | 1 | ||||
| -rw-r--r-- | nova/virt/xenapi_conn.py | 2 |
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) |
