From faed18358f534ed7a743fcd168d649d06da092ab Mon Sep 17 00:00:00 2001 From: Arvind Somy Date: Fri, 17 Jun 2011 14:02:24 -0400 Subject: Fix for Bug lp:796813 - Adding support for distributed virtual portgroups on vmware ESX(i) --- nova/virt/vmwareapi/network_utils.py | 29 ++++++++++++++++++++++++----- nova/virt/vmwareapi/vm_util.py | 23 ++++++++++++++++++----- nova/virt/vmwareapi/vmops.py | 7 ++++--- 3 files changed, 46 insertions(+), 13 deletions(-) (limited to 'nova/virt') diff --git a/nova/virt/vmwareapi/network_utils.py b/nova/virt/vmwareapi/network_utils.py index e77842535..345cd2bd0 100644 --- a/nova/virt/vmwareapi/network_utils.py +++ b/nova/virt/vmwareapi/network_utils.py @@ -45,11 +45,30 @@ def get_network_with_the_name(session, network_name="vmnet0"): networks = session._call_method(vim_util, "get_properties_for_a_collection_of_objects", "Network", vm_networks, ["summary.name"]) - for network in networks: - if network.propSet[0].val == network_name: - return network.obj - return None - + network_obj = {} + for network in vm_networks: + # Get network properties + if network._type == 'DistributedVirtualPortgroup': + props = session._call_method(vim_util, + "get_dynamic_property",network, + "DistributedVirtualPortgroup","config") + # NOTE: This only works on ESXi if the port binding is + # set to ephemeral + if props.name == network_name: + network_obj['type'] = 'DistributedVirtualPortgroup' + network_obj['dvpg'] = props.key + network_obj['dvsw'] = props.distributedVirtualSwitch.value + else: + props = session._call_method(vim_util, + "get_dynamic_property",network, + "Network","summary.name") + if props == network_name: + network_obj['type'] = 'Network' + network_obj['name'] = network_name + if (len(network_obj) > 0): + return network_obj + else: + return None def get_vswitch_for_vlan_interface(session, vlan_interface): """ diff --git a/nova/virt/vmwareapi/vm_util.py b/nova/virt/vmwareapi/vm_util.py index a2fa7600c..d23472469 100644 --- a/nova/virt/vmwareapi/vm_util.py +++ b/nova/virt/vmwareapi/vm_util.py @@ -40,7 +40,7 @@ def split_datastore_path(datastore_path): def get_vm_create_spec(client_factory, instance, data_store_name, network_name="vmnet0", - os_type="otherGuest"): + os_type="otherGuest", network_ref=None): """Builds the VM Create spec.""" config_spec = client_factory.create('ns0:VirtualMachineConfigSpec') config_spec.name = instance.name @@ -89,7 +89,7 @@ def create_controller_spec(client_factory, key): return virtual_device_config -def create_network_spec(client_factory, network_name, mac_address): +def create_network_spec(client_factory, network_name, mac_address,network_ref=None): """ Builds a config spec for the addition of a new network adapter to the VM. @@ -101,9 +101,22 @@ def create_network_spec(client_factory, network_name, mac_address): # Get the recommended card type for the VM based on the guest OS of the VM net_device = client_factory.create('ns0:VirtualPCNet32') - backing = \ - client_factory.create('ns0:VirtualEthernetCardNetworkBackingInfo') - backing.deviceName = network_name + # NOTE: Only works on ESXi if the portgroup binding is set to + # ephemeral. Invalid configuration if set to static and the NIC does + # not come up on boot if set to dynamic. + backing = None + if (network_ref['type'] == "DistributedVirtualPortgroup"): + backing = \ + client_factory.create('ns0:VirtualEthernetCardDistributedVirtualPortBackingInfo') + portgroup = \ + client_factory.create('ns0:DistributedVirtualSwitchPortConnection') + portgroup.switchUuid = network_ref['dvsw'] + portgroup.portgroupKey = network_ref['dvpg'] + backing.port = portgroup + else: + backing = \ + client_factory.create('ns0:VirtualEthernetCardNetworkBackingInfo') + backing.deviceName = network_name connectable_spec = \ client_factory.create('ns0:VirtualDeviceConnectInfo') diff --git a/nova/virt/vmwareapi/vmops.py b/nova/virt/vmwareapi/vmops.py index 5f76b0df5..d23edbdf8 100644 --- a/nova/virt/vmwareapi/vmops.py +++ b/nova/virt/vmwareapi/vmops.py @@ -116,8 +116,9 @@ class VMWareVMOps(object): net_name) if network_ref is None: raise exception.NetworkNotFoundForBridge(bridge=net_name) - - _check_if_network_bridge_exists() + return network_ref + + network_obj = _check_if_network_bridge_exists() def _get_datastore_ref(): """Get the datastore list and choose the first local storage.""" @@ -176,7 +177,7 @@ class VMWareVMOps(object): # Get the create vm config spec config_spec = vm_util.get_vm_create_spec(client_factory, instance, - data_store_name, net_name, os_type) + data_store_name, net_name, os_type, network_obj) def _execute_create_vm(): """Create VM on ESX host.""" -- cgit