summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRyu Ishimoto <ryu@midokura.jp>2011-07-21 14:16:18 +0900
committerRyu Ishimoto <ryu@midokura.jp>2011-07-21 14:16:18 +0900
commit2d678f23b4d7173b59698381d53e41dc7ccb1cd8 (patch)
tree9533cf8f43073cffbb989358e83b4c289e61a3c2
parent90adc6067b5b9c23e5380c9cfde33c049d43d4d1 (diff)
parent407e30e4843d27943e38374d61525805236319d2 (diff)
Merged lp:~~danwent/nova/network-refactoring
-rw-r--r--nova/network/xenapi_net.py87
-rw-r--r--nova/virt/libvirt/vif.py5
-rw-r--r--nova/virt/xenapi/vm_utils.py22
-rw-r--r--nova/virt/xenapi/vmops.py47
-rw-r--r--nova/virt/xenapi_conn.py5
5 files changed, 40 insertions, 126 deletions
diff --git a/nova/network/xenapi_net.py b/nova/network/xenapi_net.py
deleted file mode 100644
index e86f4017d..000000000
--- a/nova/network/xenapi_net.py
+++ /dev/null
@@ -1,87 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright (c) 2011 Citrix Systems, Inc.
-# Copyright 2011 OpenStack LLC.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-"""Implements vlans, bridges, and iptables rules using linux utilities."""
-
-import os
-
-from nova import db
-from nova import exception
-from nova import flags
-from nova import log as logging
-from nova import utils
-from nova.virt import xenapi_conn
-from nova.virt.xenapi import network_utils
-
-
-LOG = logging.getLogger("nova.xenapi_net")
-
-
-FLAGS = flags.FLAGS
-
-
-def ensure_vlan_bridge(vlan_num, bridge, bridge_interface, net_attrs=None):
- """Create a vlan and bridge unless they already exist."""
- # Open xenapi session
- LOG.debug('ENTERING ensure_vlan_bridge in xenapi net')
- url = FLAGS.xenapi_connection_url
- username = FLAGS.xenapi_connection_username
- password = FLAGS.xenapi_connection_password
- session = xenapi_conn.XenAPISession(url, username, password)
- # Check whether bridge already exists
- # Retrieve network whose name_label is "bridge"
- network_ref = network_utils.NetworkHelper.find_network_with_name_label(
- session,
- bridge)
- if network_ref is None:
- # If bridge does not exists
- # 1 - create network
- description = 'network for nova bridge %s' % bridge
- network_rec = {'name_label': bridge,
- 'name_description': description,
- 'other_config': {}}
- network_ref = session.call_xenapi('network.create', network_rec)
- # 2 - find PIF for VLAN
- # NOTE(salvatore-orlando): using double quotes inside single quotes
- # as xapi filter only support tokens in double quotes
- expr = 'field "device" = "%s" and \
- field "VLAN" = "-1"' % bridge_interface
- pifs = session.call_xenapi('PIF.get_all_records_where', expr)
- pif_ref = None
- # Multiple PIF are ok: we are dealing with a pool
- if len(pifs) == 0:
- raise Exception(
- _('Found no PIF for device %s') % bridge_interface)
- # 3 - create vlan for network
- for pif_ref in pifs.keys():
- session.call_xenapi('VLAN.create',
- pif_ref,
- str(vlan_num),
- network_ref)
- else:
- # Check VLAN tag is appropriate
- network_rec = session.call_xenapi('network.get_record', network_ref)
- # Retrieve PIFs from network
- for pif_ref in network_rec['PIFs']:
- # Retrieve VLAN from PIF
- pif_rec = session.call_xenapi('PIF.get_record', pif_ref)
- pif_vlan = int(pif_rec['VLAN'])
- # Raise an exception if VLAN != vlan_num
- if pif_vlan != vlan_num:
- raise Exception(_("PIF %(pif_rec['uuid'])s for network "
- "%(bridge)s has VLAN id %(pif_vlan)d. "
- "Expected %(vlan_num)d") % locals())
diff --git a/nova/virt/libvirt/vif.py b/nova/virt/libvirt/vif.py
index 3d9b234b8..fabedef94 100644
--- a/nova/virt/libvirt/vif.py
+++ b/nova/virt/libvirt/vif.py
@@ -26,6 +26,8 @@ from nova.virt.vif import VIFDriver
FLAGS = flags.FLAGS
+flags.DEFINE_string('libvirt_ovs_integration_bridge', 'br-int',
+ 'Name of Integration Bridge used by Open vSwitch')
class LibvirtBridge(object):
"""Linux bridge VIF for Libvirt."""
@@ -101,7 +103,7 @@ class LibvirtOpenVswitchDriver(VIFDriver):
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,
+ FLAGS.libvirt_ovs_integration_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" % \
@@ -111,7 +113,6 @@ class LibvirtOpenVswitchDriver(VIFDriver):
'script': '',
'name': dev,
'mac_address': mapping['mac']}
- print "using result = %s" % str(result)
return result
def unplug(self, instance, network, mapping):
diff --git a/nova/virt/xenapi/vm_utils.py b/nova/virt/xenapi/vm_utils.py
index 71107aff4..e63582b54 100644
--- a/nova/virt/xenapi/vm_utils.py
+++ b/nova/virt/xenapi/vm_utils.py
@@ -282,27 +282,6 @@ class VMHelper(HelperBase):
LOG.exception(exc)
raise StorageError(_('Unable to destroy VDI %s') % vdi_ref)
- @classmethod
- def create_vif(cls, session, vm_ref, network_ref, mac_address,
- dev, rxtx_cap=0):
- """Create a VIF record. Returns a Deferred that gives the new
- VIF reference."""
- vif_rec = {}
- vif_rec['device'] = str(dev)
- vif_rec['network'] = network_ref
- vif_rec['VM'] = vm_ref
- vif_rec['MAC'] = mac_address
- vif_rec['MTU'] = '1500'
- vif_rec['other_config'] = {}
- vif_rec['qos_algorithm_type'] = "ratelimit" if rxtx_cap else ''
- vif_rec['qos_algorithm_params'] = \
- {"kbps": str(rxtx_cap * 1024)} if rxtx_cap else {}
- LOG.debug(_('Creating VIF for VM %(vm_ref)s,'
- ' network %(network_ref)s.') % locals())
- vif_ref = session.call_xenapi('VIF.create', vif_rec)
- LOG.debug(_('Created VIF %(vif_ref)s for VM %(vm_ref)s,'
- ' network %(network_ref)s.') % locals())
- return vif_ref
@classmethod
def create_vdi(cls, session, sr_ref, name_label, virtual_size, read_only):
@@ -1116,7 +1095,6 @@ def _stream_disk(dev, image_type, virtual_size, image_file):
for chunk in image_file:
f.write(chunk)
-
def _write_partition(virtual_size, dev):
dest = '/dev/%s' % dev
primary_first = MBR_SIZE_SECTORS
diff --git a/nova/virt/xenapi/vmops.py b/nova/virt/xenapi/vmops.py
index c332c27b0..bdf471d16 100644
--- a/nova/virt/xenapi/vmops.py
+++ b/nova/virt/xenapi/vmops.py
@@ -52,6 +52,9 @@ FLAGS = flags.FLAGS
flags.DEFINE_integer('windows_version_timeout', 300,
'number of seconds to wait for windows agent to be '
'fully operational')
+flags.DEFINE_string('xenapi_vif_driver',
+ 'nova.virt.xenapi.vif.XenAPIBridgeDriver',
+ 'The XenAPI VIF driver using XenServer Network APIs.')
def cmp_version(a, b):
@@ -78,6 +81,7 @@ class VMOps(object):
self._session = session
self.poll_rescue_last_ran = None
VMHelper.XenAPI = self.XenAPI
+ self.vif_driver = utils.import_object(FLAGS.xenapi_vif_driver)
def list_instances(self):
"""List VM instances."""
@@ -255,7 +259,7 @@ class VMOps(object):
VMHelper.preconfigure_instance(self._session, instance,
first_vdi_ref, network_info)
- self.create_vifs(vm_ref, network_info)
+ self.create_vifs(vm_ref, instance, network_info)
self.inject_network_info(instance, network_info, vm_ref)
return vm_ref
@@ -469,7 +473,7 @@ class VMOps(object):
self._session, instance, template_vdi_uuids, image_id)
finally:
if template_vm_ref:
- self._destroy(instance, template_vm_ref,
+ self._destroy(instance, template_vm_ref, None,
shutdown=False, destroy_kernel_ramdisk=False)
logging.debug(_("Finished snapshot and upload for VM %s"), instance)
@@ -839,7 +843,7 @@ class VMOps(object):
self._session.call_xenapi("Async.VM.destroy", rescue_vm_ref)
- def destroy(self, instance):
+ def destroy(self, instance, network_info):
"""Destroy VM instance.
This is the method exposed by xenapi_conn.destroy(). The rest of the
@@ -849,9 +853,9 @@ class VMOps(object):
instance_id = instance.id
LOG.info(_("Destroying VM for Instance %(instance_id)s") % locals())
vm_ref = VMHelper.lookup(self._session, instance.name)
- return self._destroy(instance, vm_ref, shutdown=True)
+ return self._destroy(instance, vm_ref, network_info, shutdown=True)
- def _destroy(self, instance, vm_ref, shutdown=True,
+ def _destroy(self, instance, vm_ref, network_info, shutdown=True,
destroy_kernel_ramdisk=True):
"""Destroys VM instance by performing:
@@ -873,6 +877,16 @@ class VMOps(object):
self._destroy_kernel_ramdisk(instance, vm_ref)
self._destroy_vm(instance, vm_ref)
+ if network_info:
+ 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_with_callback(self, instance_id, task, callback):
ret = None
try:
@@ -1068,7 +1082,7 @@ class VMOps(object):
# catch KeyError for domid if instance isn't running
pass
- def create_vifs(self, vm_ref, network_info):
+ def create_vifs(self, vm_ref, instance, network_info):
"""Creates vifs for an instance."""
logging.debug(_("creating vif(s) for vm: |%s|"), vm_ref)
@@ -1077,14 +1091,19 @@ class VMOps(object):
self._session.get_xenapi().VM.get_record(vm_ref)
for device, (network, info) in enumerate(network_info):
- mac_address = info['mac']
- bridge = network['bridge']
- rxtx_cap = info.pop('rxtx_cap')
- network_ref = \
- NetworkHelper.find_network_with_bridge(self._session,
- bridge)
- VMHelper.create_vif(self._session, vm_ref, network_ref,
- mac_address, device, rxtx_cap)
+ vif_rec = self.vif_driver.get_vif_rec(self._session,
+ vm_ref, instance, device, network, info)
+ network_ref = vif_rec['network']
+ LOG.debug(_('Creating VIF for VM %(vm_ref)s,' \
+ ' network %(network_ref)s.') % locals())
+ vif_ref = self._session.call_xenapi('VIF.create', vif_rec)
+ LOG.debug(_('Created VIF %(vif_ref)s for VM %(vm_ref)s,'
+ ' network %(network_ref)s.') % locals())
+
+ def plug_vifs(instance, network_info):
+ """Set up VIF networking on the host."""
+ for (network, mapping) in network_info:
+ self.vif_driver.plug(self._session, instance, network, mapping)
def reset_network(self, instance, vm_ref=None):
"""Creates uuid arg to pass to make_agent_call and calls it."""
diff --git a/nova/virt/xenapi_conn.py b/nova/virt/xenapi_conn.py
index b8e5251a9..102278e1c 100644
--- a/nova/virt/xenapi_conn.py
+++ b/nova/virt/xenapi_conn.py
@@ -226,7 +226,7 @@ class XenAPIConnection(driver.ComputeDriver):
def destroy(self, instance, network_info):
"""Destroy VM instance"""
- self._vmops.destroy(instance)
+ self._vmops.destroy(instance, network_info)
def pause(self, instance, callback):
"""Pause VM instance"""
@@ -269,6 +269,9 @@ class XenAPIConnection(driver.ComputeDriver):
"""inject network info for specified instance"""
self._vmops.inject_network_info(instance, network_info)
+ def plug_vifs(self, instance_ref, network_info):
+ self._vmops.plug_vifs(instance_ref, network_info)
+
def get_info(self, instance_id):
"""Return data about VM instance"""
return self._vmops.get_info(instance_id)