From 6fafda1ffbf2838ef33a4948303f24ed075c292d Mon Sep 17 00:00:00 2001 From: Ryu Ishimoto Date: Wed, 20 Jul 2011 06:42:49 +0900 Subject: Renamed setup_vif_network to plug_vif --- nova/compute/manager.py | 20 ++++++++++++-------- nova/network/manager.py | 4 +++- nova/virt/libvirt/connection.py | 11 ++++------- nova/virt/libvirt/vif.py | 16 ++++------------ nova/virt/vif.py | 4 ++-- 5 files changed, 25 insertions(+), 30 deletions(-) diff --git a/nova/compute/manager.py b/nova/compute/manager.py index eb52995be..0894052ce 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -299,7 +299,7 @@ class ComputeManager(manager.SchedulerDependentManager): network_info = self.network_api.allocate_for_instance(context, instance, vpn=is_vpn) LOG.debug(_("instance network_info: |%s|"), network_info) - self.driver.setup_vif_network(context, instance['id']) + self.driver.plug_vifs(context, instance, network_info) else: # TODO(tr3buchet) not really sure how this should be handled. # virt requires network_info to be passed in but stub_network @@ -356,7 +356,7 @@ class ComputeManager(manager.SchedulerDependentManager): network_info = None if not FLAGS.stub_network: network_info = self.network_api.get_instance_nw_info(context, - instance) + instance) self.network_api.deallocate_for_instance(context, instance) volumes = instance.get('volumes') or [] @@ -414,7 +414,7 @@ class ComputeManager(manager.SchedulerDependentManager): self._update_state(context, instance_id, power_state.BUILDING) network_info = self.network_api.get_instance_nw_info(context, - instance_ref) + instance_ref) self.driver.destroy(instance_ref, network_info) image_ref = kwargs.get('image_ref') instance_ref.image_ref = image_ref @@ -642,7 +642,9 @@ class ComputeManager(manager.SchedulerDependentManager): instance_id, power_state.NOSTATE, 'rescuing') - self.driver.setup_vif_network(context, instance_id) + network_info = self.network_api.get_instance_nw_info(context, + instance_ref) + self.driver.plug_vifs(context, instance_ref, network_info) _update_state = lambda result: self._update_state_callback( self, context, instance_id, result) self.driver.rescue(instance_ref, _update_state) @@ -677,7 +679,7 @@ class ComputeManager(manager.SchedulerDependentManager): instance_ref = self.db.instance_get(context, instance_id) network_info = self.network_api.get_instance_nw_info(context, - instance_ref) + instance_ref) self.driver.destroy(instance_ref, network_info) usage_info = utils.usage_from_instance(instance_ref) notifier.notify('compute.%s' % self.host, @@ -698,7 +700,7 @@ class ComputeManager(manager.SchedulerDependentManager): migration_ref = self.db.migration_get(context, migration_id) network_info = self.network_api.get_instance_nw_info(context, - instance_ref) + instance_ref) self.driver.destroy(instance_ref, network_info) topic = self.db.queue_get_for(context, FLAGS.compute_topic, instance_ref['host']) @@ -1203,16 +1205,18 @@ class ComputeManager(manager.SchedulerDependentManager): # # Retry operation is necessary because continuously request comes, # concorrent request occurs to iptables, then it complains. + network_info = self.network_api.get_instance_nw_info(context, + instance_ref) max_retry = FLAGS.live_migration_retry_count for cnt in range(max_retry): try: - self.driver.setup_vif_network(context, instance_id) + self.driver.plug_vifs(context, instance_ref, network_info) break except exception.ProcessExecutionError: if cnt == max_retry - 1: raise else: - LOG.warn(_("setup_vif_network() failed %(cnt)d." + LOG.warn(_("plug_vifs() failed %(cnt)d." "Retry up to %(max_retry)d for %(hostname)s.") % locals()) time.sleep(1) diff --git a/nova/network/manager.py b/nova/network/manager.py index d5b8cf8dc..bf83bf4e6 100644 --- a/nova/network/manager.py +++ b/nova/network/manager.py @@ -444,7 +444,9 @@ class NetworkManager(manager.SchedulerDependentManager): 'id': network['id'], 'cidr': network['cidr'], 'cidr_v6': network['cidr_v6'], - 'injected': network['injected']} + 'injected': network['injected'], + 'vlan': network['vlan'], + 'bridge_interface': network['bridge_interface']} info = { 'label': network['label'], 'gateway': network['gateway'], diff --git a/nova/virt/libvirt/connection.py b/nova/virt/libvirt/connection.py index 936e1b171..572503311 100644 --- a/nova/virt/libvirt/connection.py +++ b/nova/virt/libvirt/connection.py @@ -259,13 +259,10 @@ class LibvirtConnection(driver.ComputeDriver): infos.append(info) return infos - def setup_vif_network(self, ctxt, instance_id): - """Set up VIF networking on the host.""" - # 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 plug_vifs(self, ctxt, instance, network_info): + """Plugin VIFs into networks.""" + for (network, mapping) in network_info: + self.vif_driver.plug(instance, network, mapping) def destroy(self, instance, network_info, cleanup=True): instance_name = instance['name'] diff --git a/nova/virt/libvirt/vif.py b/nova/virt/libvirt/vif.py index 4f7bb0b4d..820055cf0 100644 --- a/nova/virt/libvirt/vif.py +++ b/nova/virt/libvirt/vif.py @@ -30,15 +30,7 @@ flags.DEFINE_bool('allow_project_net_traffic', 'Whether to allow in project network traffic') -class LibvirtVIF(object): - """VIF class for libvirt""" - - def get_configurations(self, instance, network, mapping): - """Get a dictionary of VIF configuration for libvirt interfaces.""" - raise NotImplementedError() - - -class LibvirtBridge(LibvirtVIF): +class LibvirtBridge(object): """Linux bridge VIF for Libvirt.""" def get_configurations(self, instance, network, mapping): @@ -80,7 +72,7 @@ class LibvirtBridge(LibvirtVIF): class LibvirtBridgeDriver(VIFDriver, LibvirtBridge): """VIF driver for Linux bridge.""" - def plug(self, network): + def plug(self, instance, network, mapping): """Ensure that the bridge exists, and add VIF to it.""" linux_net.ensure_bridge(network['bridge'], network['bridge_interface']) @@ -92,7 +84,7 @@ class LibvirtBridgeDriver(VIFDriver, LibvirtBridge): class LibvirtVlanBridgeDriver(VIFDriver, LibvirtBridge): """VIF driver for Linux bridge with VLAN.""" - def plug(self, network): + def plug(self, instance, network, mapping): """Ensure that VLAN and bridge exist and add VIF to the bridge.""" linux_net.ensure_vlan_bridge(network['vlan'], network['bridge'], network['bridge_interface']) @@ -123,7 +115,7 @@ class LibvirtOpenVswitchDriver(VIFDriver): print "using result = %s" % str(result) return result - def plug(self, network): + def plug(self, instance, network, mapping): pass def unplug(self, instance, network, mapping): diff --git a/nova/virt/vif.py b/nova/virt/vif.py index bab1bdac9..b78689957 100644 --- a/nova/virt/vif.py +++ b/nova/virt/vif.py @@ -21,10 +21,10 @@ class VIFDriver(object): """Abstract class that defines generic interfaces for all VIF drivers.""" - def plug(self, network): + def plug(self, instance, network, mapping): """Plug VIF into network.""" raise NotImplementedError() - def unplug(self, network): + def unplug(self, instance, network, mapping): """Unplug VIF from network.""" raise NotImplementedError() -- cgit From 798a5e31b304df1c59e226f9426c07cb250dae16 Mon Sep 17 00:00:00 2001 From: Ryu Ishimoto Date: Wed, 20 Jul 2011 20:21:44 +0900 Subject: Added network_info parameter to all the appropriate places in virt layers and compute manager --- nova/compute/manager.py | 12 ++++++++---- nova/virt/driver.py | 10 +++++----- nova/virt/fake.py | 8 ++++---- nova/virt/hyperv.py | 6 +++--- nova/virt/libvirt/connection.py | 14 +++++++------- nova/virt/vmwareapi_conn.py | 6 +++--- nova/virt/xenapi_conn.py | 6 +++--- 7 files changed, 33 insertions(+), 29 deletions(-) diff --git a/nova/compute/manager.py b/nova/compute/manager.py index 0894052ce..98f3cc86f 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -419,7 +419,7 @@ class ComputeManager(manager.SchedulerDependentManager): image_ref = kwargs.get('image_ref') instance_ref.image_ref = image_ref instance_ref.injected_files = kwargs.get('injected_files', []) - self.driver.spawn(instance_ref) + self.driver.spawn(instance_ref, network_info) self._update_image_ref(context, instance_id, image_ref) self._update_launched_at(context, instance_id) @@ -452,7 +452,9 @@ class ComputeManager(manager.SchedulerDependentManager): instance_id, power_state.NOSTATE, 'rebooting') - self.driver.reboot(instance_ref) + network_info = self.network_api.get_instance_nw_info(context, + instance_ref) + self.driver.reboot(instance_ref, network_info) self._update_state(context, instance_id) @exception.wrap_exception(notifier=notifier, publisher_id=publisher_id()) @@ -647,7 +649,7 @@ class ComputeManager(manager.SchedulerDependentManager): self.driver.plug_vifs(context, instance_ref, network_info) _update_state = lambda result: self._update_state_callback( self, context, instance_id, result) - self.driver.rescue(instance_ref, _update_state) + self.driver.rescue(instance_ref, _update_state, network_info) self._update_state(context, instance_id) @exception.wrap_exception(notifier=notifier, publisher_id=publisher_id()) @@ -663,7 +665,9 @@ class ComputeManager(manager.SchedulerDependentManager): 'unrescuing') _update_state = lambda result: self._update_state_callback( self, context, instance_id, result) - self.driver.unrescue(instance_ref, _update_state) + network_info = self.network_api.get_instance_nw_info(context, + instance_ref) + self.driver.unrescue(instance_ref, _update_state, network_info) self._update_state(context, instance_id) @staticmethod diff --git a/nova/virt/driver.py b/nova/virt/driver.py index 178279d31..61f26ad96 100644 --- a/nova/virt/driver.py +++ b/nova/virt/driver.py @@ -61,11 +61,11 @@ class ComputeDriver(object): """Return a list of InstanceInfo for all registered VMs""" raise NotImplementedError() - def spawn(self, instance, network_info=None, block_device_mapping=None): + def spawn(self, instance, network_info, block_device_mapping=None): """Launch a VM for the specified instance""" raise NotImplementedError() - def destroy(self, instance, cleanup=True): + def destroy(self, instance, network_info, cleanup=True): """Destroy (shutdown and delete) the specified instance. The given parameter is an instance of nova.compute.service.Instance, @@ -81,7 +81,7 @@ class ComputeDriver(object): """ raise NotImplementedError() - def reboot(self, instance): + def reboot(self, instance, network_info): """Reboot specified VM""" raise NotImplementedError() @@ -146,11 +146,11 @@ class ComputeDriver(object): """resume the specified instance""" raise NotImplementedError() - def rescue(self, instance, callback): + def rescue(self, instance, callback, network_info): """Rescue the specified instance""" raise NotImplementedError() - def unrescue(self, instance, callback): + def unrescue(self, instance, callback, network_info): """Unrescue the specified instance""" raise NotImplementedError() diff --git a/nova/virt/fake.py b/nova/virt/fake.py index ea0a59f21..c5e9d89e4 100644 --- a/nova/virt/fake.py +++ b/nova/virt/fake.py @@ -167,7 +167,7 @@ class FakeConnection(driver.ComputeDriver): """ pass - def reboot(self, instance): + def reboot(self, instance, network_info): """ Reboot the specified instance. @@ -240,13 +240,13 @@ class FakeConnection(driver.ComputeDriver): """ pass - def rescue(self, instance): + def rescue(self, instance, callback, network_info): """ Rescue the specified instance. """ pass - def unrescue(self, instance): + def unrescue(self, instance, callback, network_info): """ Unrescue the specified instance. """ @@ -293,7 +293,7 @@ class FakeConnection(driver.ComputeDriver): """ pass - def destroy(self, instance): + def destroy(self, instance, network_info): key = instance.name if key in self.instances: del self.instances[key] diff --git a/nova/virt/hyperv.py b/nova/virt/hyperv.py index 5c1dc772d..81c7dea58 100644 --- a/nova/virt/hyperv.py +++ b/nova/virt/hyperv.py @@ -139,7 +139,7 @@ class HyperVConnection(driver.ComputeDriver): return instance_infos - def spawn(self, instance, network_info=None, block_device_mapping=None): + def spawn(self, instance, network_info, block_device_mapping=None): """ Create a new VM and start it.""" vm = self._lookup(instance.name) if vm is not None: @@ -368,14 +368,14 @@ class HyperVConnection(driver.ComputeDriver): wmi_obj.Properties_.Item(prop).Value return newinst - def reboot(self, instance): + def reboot(self, instance, network_info): """Reboot the specified instance.""" vm = self._lookup(instance.name) if vm is None: raise exception.InstanceNotFound(instance_id=instance.id) self._set_vm_state(instance.name, 'Reboot') - def destroy(self, instance): + def destroy(self, instance, network_info): """Destroy the VM. Also destroy the associated VHD disk files""" LOG.debug(_("Got request to destroy vm %s"), instance.name) vm = self._lookup(instance.name) diff --git a/nova/virt/libvirt/connection.py b/nova/virt/libvirt/connection.py index 572503311..5f347989c 100644 --- a/nova/virt/libvirt/connection.py +++ b/nova/virt/libvirt/connection.py @@ -477,7 +477,7 @@ class LibvirtConnection(driver.ComputeDriver): shutil.rmtree(temp_dir) @exception.wrap_exception() - def reboot(self, instance): + def reboot(self, instance, network_info): """Reboot a virtual machine, given an instance reference. This method actually destroys and re-creates the domain to ensure the @@ -492,7 +492,7 @@ class LibvirtConnection(driver.ComputeDriver): # NOTE(itoumsn): self.shutdown() and wait instead of self.destroy() is # better because we cannot ensure flushing dirty buffers # in the guest OS. But, in case of KVM, shutdown() does not work... - self.destroy(instance, False) + self.destroy(instance, network_info, cleanup=False) self.firewall_driver.setup_basic_filtering(instance) self.firewall_driver.prepare_instance_filter(instance) self._create_new_domain(xml) @@ -542,7 +542,7 @@ class LibvirtConnection(driver.ComputeDriver): dom.create() @exception.wrap_exception() - def rescue(self, instance): + def rescue(self, instance, callback, network_info): """Loads a VM using rescue images. A rescue is normally performed when something goes wrong with the @@ -551,7 +551,7 @@ class LibvirtConnection(driver.ComputeDriver): data recovery. """ - self.destroy(instance, False) + self.destroy(instance, network_info, cleanup=False) xml = self.to_xml(instance, rescue=True) rescue_images = {'image_id': FLAGS.rescue_image_id, @@ -580,14 +580,14 @@ class LibvirtConnection(driver.ComputeDriver): return timer.start(interval=0.5, now=True) @exception.wrap_exception() - def unrescue(self, instance): + def unrescue(self, instance, network_info): """Reboot the VM which is being rescued back into primary images. Because reboot destroys and re-creates instances, unresue should simply call reboot. """ - self.reboot(instance) + self.reboot(instance, network_info) @exception.wrap_exception() def poll_rescued_instances(self, timeout): @@ -596,7 +596,7 @@ class LibvirtConnection(driver.ComputeDriver): # NOTE(ilyaalekseyev): Implementation like in multinics # for xenapi(tr3buchet) @exception.wrap_exception() - def spawn(self, instance, network_info=None, block_device_mapping=None): + def spawn(self, instance, network_info, block_device_mapping=None): xml = self.to_xml(instance, False, network_info=network_info, block_device_mapping=block_device_mapping) block_device_mapping = block_device_mapping or [] diff --git a/nova/virt/vmwareapi_conn.py b/nova/virt/vmwareapi_conn.py index d80e14931..9e15510ab 100644 --- a/nova/virt/vmwareapi_conn.py +++ b/nova/virt/vmwareapi_conn.py @@ -124,7 +124,7 @@ class VMWareESXConnection(driver.ComputeDriver): """List VM instances.""" return self._vmops.list_instances() - def spawn(self, instance, network_info=None, block_device_mapping=None): + def spawn(self, instance, network_info, block_device_mapping=None): """Create VM instance.""" self._vmops.spawn(instance) @@ -132,11 +132,11 @@ class VMWareESXConnection(driver.ComputeDriver): """Create snapshot from a running VM instance.""" self._vmops.snapshot(instance, name) - def reboot(self, instance): + def reboot(self, instance, network_info): """Reboot VM instance.""" self._vmops.reboot(instance) - def destroy(self, instance): + def destroy(self, instance, network_info): """Destroy VM instance.""" self._vmops.destroy(instance) diff --git a/nova/virt/xenapi_conn.py b/nova/virt/xenapi_conn.py index 032ab7345..b8e5251a9 100644 --- a/nova/virt/xenapi_conn.py +++ b/nova/virt/xenapi_conn.py @@ -210,7 +210,7 @@ class XenAPIConnection(driver.ComputeDriver): """ Create snapshot from a running VM instance """ self._vmops.snapshot(instance, image_id) - def reboot(self, instance): + def reboot(self, instance, network_info): """Reboot VM instance""" self._vmops.reboot(instance) @@ -249,11 +249,11 @@ class XenAPIConnection(driver.ComputeDriver): """resume the specified instance""" self._vmops.resume(instance, callback) - def rescue(self, instance, callback): + def rescue(self, instance, callback, network_info): """Rescue the specified instance""" self._vmops.rescue(instance, callback) - def unrescue(self, instance, callback): + def unrescue(self, instance, callback, network_info): """Unrescue the specified instance""" self._vmops.unrescue(instance, callback) -- cgit From 7bdd244541fd9cef4031d4050b5200f58a15f757 Mon Sep 17 00:00:00 2001 From: Ryu Ishimoto Date: Wed, 20 Jul 2011 21:00:20 +0900 Subject: Moved ensure_vlan_bridge of vmware to VIF driver --- nova/network/vmwareapi_net.py | 82 -------------------------------------- nova/virt/vmwareapi/vif.py | 93 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 93 insertions(+), 82 deletions(-) delete mode 100644 nova/network/vmwareapi_net.py create mode 100644 nova/virt/vmwareapi/vif.py diff --git a/nova/network/vmwareapi_net.py b/nova/network/vmwareapi_net.py deleted file mode 100644 index b32cf3303..000000000 --- a/nova/network/vmwareapi_net.py +++ /dev/null @@ -1,82 +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 for vmwareapi.""" - -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.vmwareapi_conn import VMWareAPISession -from nova.virt.vmwareapi import network_utils - - -LOG = logging.getLogger("nova.network.vmwareapi_net") - - -FLAGS = flags.FLAGS -FLAGS['vlan_interface'].SetDefault('vmnic0') - - -def ensure_vlan_bridge(vlan_num, bridge, bridge_interface, net_attrs=None): - """Create a vlan and bridge unless they already exist.""" - # Open vmwareapi session - host_ip = FLAGS.vmwareapi_host_ip - host_username = FLAGS.vmwareapi_host_username - host_password = FLAGS.vmwareapi_host_password - if not host_ip or host_username is None or host_password is None: - raise Exception(_('Must specify vmwareapi_host_ip, ' - 'vmwareapi_host_username ' - 'and vmwareapi_host_password to use ' - 'connection_type=vmwareapi')) - session = VMWareAPISession(host_ip, host_username, host_password, - FLAGS.vmwareapi_api_retry_count) - vlan_interface = bridge_interface - # Check if the vlan_interface physical network adapter exists on the host - if not network_utils.check_if_vlan_interface_exists(session, - vlan_interface): - raise exception.NetworkAdapterNotFound(adapter=vlan_interface) - - # Get the vSwitch associated with the Physical Adapter - vswitch_associated = network_utils.get_vswitch_for_vlan_interface( - session, vlan_interface) - if vswitch_associated is None: - raise exception.SwicthNotFoundForNetworkAdapter(adapter=vlan_interface) - # Check whether bridge already exists and retrieve the the ref of the - # network whose name_label is "bridge" - network_ref = network_utils.get_network_with_the_name(session, bridge) - if network_ref is None: - # Create a port group on the vSwitch associated with the vlan_interface - # corresponding physical network adapter on the ESX host - network_utils.create_port_group(session, bridge, vswitch_associated, - vlan_num) - else: - # Get the vlan id and vswitch corresponding to the port group - pg_vlanid, pg_vswitch = \ - network_utils.get_vlanid_and_vswitch_for_portgroup(session, bridge) - - # Check if the vswitch associated is proper - if pg_vswitch != vswitch_associated: - raise exception.InvalidVLANPortGroup(bridge=bridge, - expected=vswitch_associated, - actual=pg_vswitch) - - # Check if the vlan id is proper for the port group - if pg_vlanid != vlan_num: - raise exception.InvalidVLANTag(bridge=bridge, tag=vlan_num, - pgroup=pg_vlanid) diff --git a/nova/virt/vmwareapi/vif.py b/nova/virt/vmwareapi/vif.py new file mode 100644 index 000000000..902699089 --- /dev/null +++ b/nova/virt/vmwareapi/vif.py @@ -0,0 +1,93 @@ +# 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. + +"""VIF drivers for VMWare.""" + +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.vif import VIFDriver +from nova.virt.vmwareapi_conn import VMWareAPISession +from nova.virt.vmwareapi import network_utils + + +LOG = logging.getLogger("nova.virt.vmwareapi.vif") + +FLAGS = flags.FLAGS + + +class VMWareVlanBridgeDriver(VIFDriver): + """VIF driver for Linux VLAN bridge.""" + + def plug(self, instance, network, mapping): + """Create a vlan and bridge unless they already exist.""" + vlan_num = network['vlan'] + bridge = network['bridge'] + bridge_interface = network['bridge_interface'] + + # Open vmwareapi session + host_ip = FLAGS.vmwareapi_host_ip + host_username = FLAGS.vmwareapi_host_username + host_password = FLAGS.vmwareapi_host_password + if not host_ip or host_username is None or host_password is None: + raise Exception(_('Must specify vmwareapi_host_ip, ' + 'vmwareapi_host_username ' + 'and vmwareapi_host_password to use ' + 'connection_type=vmwareapi')) + session = VMWareAPISession(host_ip, host_username, host_password, + FLAGS.vmwareapi_api_retry_count) + vlan_interface = bridge_interface + # Check if the vlan_interface physical network adapter exists on the host + if not network_utils.check_if_vlan_interface_exists(session, + vlan_interface): + raise exception.NetworkAdapterNotFound(adapter=vlan_interface) + + # Get the vSwitch associated with the Physical Adapter + vswitch_associated = network_utils.get_vswitch_for_vlan_interface( + session, vlan_interface) + if vswitch_associated is None: + raise exception.SwicthNotFoundForNetworkAdapter(adapter=vlan_interface) + # Check whether bridge already exists and retrieve the the ref of the + # network whose name_label is "bridge" + network_ref = network_utils.get_network_with_the_name(session, bridge) + if network_ref is None: + # Create a port group on the vSwitch associated with the vlan_interface + # corresponding physical network adapter on the ESX host + network_utils.create_port_group(session, bridge, vswitch_associated, + vlan_num) + else: + # Get the vlan id and vswitch corresponding to the port group + pg_vlanid, pg_vswitch = \ + network_utils.get_vlanid_and_vswitch_for_portgroup(session, bridge) + + # Check if the vswitch associated is proper + if pg_vswitch != vswitch_associated: + raise exception.InvalidVLANPortGroup(bridge=bridge, + expected=vswitch_associated, + actual=pg_vswitch) + + # Check if the vlan id is proper for the port group + if pg_vlanid != vlan_num: + raise exception.InvalidVLANTag(bridge=bridge, tag=vlan_num, + pgroup=pg_vlanid) + + + def unplug(self, instance, network, mapping): + pass + -- cgit From 0c66b0b8caad7437fa2afd64a2038bcb166c83a5 Mon Sep 17 00:00:00 2001 From: Ryu Ishimoto Date: Wed, 20 Jul 2011 21:34:30 +0900 Subject: Merged get_configurations and plug of VIF drivers --- nova/compute/manager.py | 2 -- nova/virt/libvirt/connection.py | 3 +-- nova/virt/libvirt/vif.py | 9 ++++----- 3 files changed, 5 insertions(+), 9 deletions(-) diff --git a/nova/compute/manager.py b/nova/compute/manager.py index 98f3cc86f..2ade43503 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -299,7 +299,6 @@ class ComputeManager(manager.SchedulerDependentManager): network_info = self.network_api.allocate_for_instance(context, instance, vpn=is_vpn) LOG.debug(_("instance network_info: |%s|"), network_info) - self.driver.plug_vifs(context, instance, network_info) else: # TODO(tr3buchet) not really sure how this should be handled. # virt requires network_info to be passed in but stub_network @@ -646,7 +645,6 @@ class ComputeManager(manager.SchedulerDependentManager): 'rescuing') network_info = self.network_api.get_instance_nw_info(context, instance_ref) - self.driver.plug_vifs(context, instance_ref, network_info) _update_state = lambda result: self._update_state_callback( self, context, instance_id, result) self.driver.rescue(instance_ref, _update_state, network_info) diff --git a/nova/virt/libvirt/connection.py b/nova/virt/libvirt/connection.py index 5f347989c..5cedcf2c1 100644 --- a/nova/virt/libvirt/connection.py +++ b/nova/virt/libvirt/connection.py @@ -966,8 +966,7 @@ class LibvirtConnection(driver.ComputeDriver): nics = [] for (network, mapping) in network_info: - nics.append(self.vif_driver.get_configurations(instance, network, - mapping)) + nics.append(self.vif_driver.plug(instance, network, mapping)) # FIXME(vish): stick this in db inst_type_id = instance['instance_type_id'] inst_type = instance_types.get_instance_type(inst_type_id) diff --git a/nova/virt/libvirt/vif.py b/nova/virt/libvirt/vif.py index 820055cf0..d35a3c8f6 100644 --- a/nova/virt/libvirt/vif.py +++ b/nova/virt/libvirt/vif.py @@ -33,7 +33,7 @@ flags.DEFINE_bool('allow_project_net_traffic', class LibvirtBridge(object): """Linux bridge VIF for Libvirt.""" - def get_configurations(self, instance, network, mapping): + def get_configurations(self, network, mapping): """Get a dictionary of VIF configurations for bridge type.""" # Assume that the gateway also acts as the dhcp server. dhcp_server = mapping['gateway'] @@ -76,6 +76,7 @@ class LibvirtBridgeDriver(VIFDriver, LibvirtBridge): """Ensure that the bridge exists, and add VIF to it.""" linux_net.ensure_bridge(network['bridge'], network['bridge_interface']) + return self.get_configurations(network, mapping) def unplug(self, instance, network, mapping): pass @@ -88,6 +89,7 @@ class LibvirtVlanBridgeDriver(VIFDriver, LibvirtBridge): """Ensure that VLAN and bridge exist and add VIF to the bridge.""" linux_net.ensure_vlan_bridge(network['vlan'], network['bridge'], network['bridge_interface']) + return self.get_configurations(network, mapping) def unplug(self, instance, network, mapping): pass @@ -96,7 +98,7 @@ class LibvirtVlanBridgeDriver(VIFDriver, LibvirtBridge): class LibvirtOpenVswitchDriver(VIFDriver): """VIF driver for Open vSwitch.""" - def get_configurations(self, instance, network, mapping): + def plug(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') @@ -115,9 +117,6 @@ class LibvirtOpenVswitchDriver(VIFDriver): print "using result = %s" % str(result) return result - def plug(self, instance, network, mapping): - pass - def unplug(self, instance, network, mapping): vif_id = str(instance['id']) + "-" + str(network['id']) dev = "tap-%s" % vif_id -- cgit From 27d8dc42120d3cefc91bf6510f215dfdef7f23d2 Mon Sep 17 00:00:00 2001 From: Ryu Ishimoto Date: Wed, 20 Jul 2011 22:21:48 +0900 Subject: Removed unnecessary context parameter --- nova/compute/manager.py | 2 +- nova/virt/driver.py | 5 +++++ nova/virt/libvirt/connection.py | 3 ++- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/nova/compute/manager.py b/nova/compute/manager.py index 2ade43503..cc5cf747c 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -1212,7 +1212,7 @@ class ComputeManager(manager.SchedulerDependentManager): max_retry = FLAGS.live_migration_retry_count for cnt in range(max_retry): try: - self.driver.plug_vifs(context, instance_ref, network_info) + self.driver.plug_vifs(instance_ref, network_info) break except exception.ProcessExecutionError: if cnt == max_retry - 1: diff --git a/nova/virt/driver.py b/nova/virt/driver.py index 61f26ad96..e8dcf138b 100644 --- a/nova/virt/driver.py +++ b/nova/virt/driver.py @@ -253,3 +253,8 @@ class ComputeDriver(object): def set_host_enabled(self, host, enabled): """Sets the specified host's ability to accept new instances.""" raise NotImplementedError() + + def plug_vifs(self, instance, network_info): + """Plugs in VIFs to networks.""" + raise NotImplementedError() + diff --git a/nova/virt/libvirt/connection.py b/nova/virt/libvirt/connection.py index 5cedcf2c1..3f6230e95 100644 --- a/nova/virt/libvirt/connection.py +++ b/nova/virt/libvirt/connection.py @@ -259,7 +259,7 @@ class LibvirtConnection(driver.ComputeDriver): infos.append(info) return infos - def plug_vifs(self, ctxt, instance, network_info): + def plug_vifs(self, instance, network_info): """Plugin VIFs into networks.""" for (network, mapping) in network_info: self.vif_driver.plug(instance, network, mapping) @@ -493,6 +493,7 @@ class LibvirtConnection(driver.ComputeDriver): # better because we cannot ensure flushing dirty buffers # in the guest OS. But, in case of KVM, shutdown() does not work... self.destroy(instance, network_info, cleanup=False) + self.plug_vifs(instance, network_info) self.firewall_driver.setup_basic_filtering(instance) self.firewall_driver.prepare_instance_filter(instance) self._create_new_domain(xml) -- cgit From 2bfa91575d36363b16c25c29623f7ac988e844bb Mon Sep 17 00:00:00 2001 From: Ryu Ishimoto Date: Wed, 20 Jul 2011 22:22:07 +0900 Subject: First attempt at vmware API VIF driver integration --- nova/virt/vmwareapi/vmops.py | 29 ++++++++++++++++++++++++++--- nova/virt/vmwareapi_conn.py | 9 ++++++--- 2 files changed, 32 insertions(+), 6 deletions(-) diff --git a/nova/virt/vmwareapi/vmops.py b/nova/virt/vmwareapi/vmops.py index 94d9e6226..eded4391e 100644 --- a/nova/virt/vmwareapi/vmops.py +++ b/nova/virt/vmwareapi/vmops.py @@ -31,6 +31,7 @@ from nova import db from nova import exception from nova import flags from nova import log as logging +from nova import utils from nova.compute import power_state from nova.virt.vmwareapi import vim_util from nova.virt.vmwareapi import vm_util @@ -38,6 +39,10 @@ from nova.virt.vmwareapi import vmware_images from nova.virt.vmwareapi import network_utils FLAGS = flags.FLAGS +flags.DEFINE_string('vmware_vif_driver', + 'nova.virt.vmwareapi.vif.VMWareVlanBridgeDriver', + 'The VMWare VIF driver to configure the VIFs.') + LOG = logging.getLogger("nova.virt.vmwareapi.vmops") VMWARE_POWER_STATES = { @@ -52,6 +57,7 @@ class VMWareVMOps(object): def __init__(self, session): """Initializer.""" self._session = session + self._vif_driver = utils.import_object(FLAGS.vmware_vif_driver) def _wait_with_callback(self, instance_id, task, callback): """Waits for the task to finish and does a callback after.""" @@ -83,7 +89,7 @@ class VMWareVMOps(object): LOG.debug(_("Got total of %s instances") % str(len(lst_vm_names))) return lst_vm_names - def spawn(self, instance): + def spawn(self, instance, network_info): """ Creates a VM instance. @@ -117,6 +123,7 @@ class VMWareVMOps(object): if network_ref is None: raise exception.NetworkNotFoundForBridge(bridge=net_name) + self.plug_vifs(instance, network_info) _check_if_network_bridge_exists() def _get_datastore_ref(): @@ -472,11 +479,14 @@ class VMWareVMOps(object): _clean_temp_data() - def reboot(self, instance): + def reboot(self, instance, network_info): """Reboot a VM instance.""" vm_ref = self._get_vm_ref_from_the_name(instance.name) if vm_ref is None: raise exception.InstanceNotFound(instance_id=instance.id) + + self.plug_vifs(instance, network_info) + lst_properties = ["summary.guest.toolsStatus", "runtime.powerState", "summary.guest.toolsRunningStatus"] props = self._session._call_method(vim_util, "get_object_properties", @@ -514,7 +524,7 @@ class VMWareVMOps(object): self._session._wait_for_task(instance.id, reset_task) LOG.debug(_("Did hard reboot of VM %s") % instance.name) - def destroy(self, instance): + def destroy(self, instance, network_info): """ Destroy a VM instance. Steps followed are: 1. Power off the VM, if it is in poweredOn state. @@ -560,6 +570,8 @@ class VMWareVMOps(object): LOG.warn(_("In vmwareapi:vmops:destroy, got this exception" " while un-registering the VM: %s") % str(excep)) + self._unplug_vifs(instance, network_info) + # Delete the folder holding the VM related content on # the datastore. try: @@ -784,3 +796,14 @@ class VMWareVMOps(object): if vm.propSet[0].val == vm_name: return vm.obj return None + + def plug_vifs(self, instance, network_info): + """Plug VIFs into networks.""" + for (network, mapping) in network_info: + self._vif_driver.plug(instance, network, mapping) + + def _unplug_vifs(self, instance, network_info): + """Unplug VIFs from networks.""" + for (network, mapping) in network_info: + self._vif_driver.unplug(instance, network, mapping) + diff --git a/nova/virt/vmwareapi_conn.py b/nova/virt/vmwareapi_conn.py index 9e15510ab..2492c9951 100644 --- a/nova/virt/vmwareapi_conn.py +++ b/nova/virt/vmwareapi_conn.py @@ -126,7 +126,7 @@ class VMWareESXConnection(driver.ComputeDriver): def spawn(self, instance, network_info, block_device_mapping=None): """Create VM instance.""" - self._vmops.spawn(instance) + self._vmops.spawn(instance, network_info) def snapshot(self, instance, name): """Create snapshot from a running VM instance.""" @@ -134,11 +134,11 @@ class VMWareESXConnection(driver.ComputeDriver): def reboot(self, instance, network_info): """Reboot VM instance.""" - self._vmops.reboot(instance) + self._vmops.reboot(instance, network_info) 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.""" @@ -194,6 +194,9 @@ class VMWareESXConnection(driver.ComputeDriver): """Sets the specified host's ability to accept new instances.""" pass + def plug_vifs(self, instance, network_info): + """Plugs in VIFs to networks.""" + self._vmops.plug_vifs(instance, network_info) class VMWareAPISession(object): """ -- cgit