Merge lp:~asomya/nova/dev into lp:~hudson-openstack/nova/trunk

Proposed by Arvind Somya
Status: Merged
Approved by: Vish Ishaya
Approved revision: 1283
Merged at revision: 1316
Proposed branch: lp:~asomya/nova/dev
Merge into: lp:~hudson-openstack/nova/trunk
Diff against target: 255 lines (+113/-18)
5 files modified
Authors (+1/-0)
nova/virt/vmwareapi/network_utils.py (+24/-4)
nova/virt/vmwareapi/vm_util.py (+25/-7)
nova/virt/vmwareapi/vmops.py (+11/-4)
tools/esx/guest_tool.py (+52/-3)
To merge this branch: bzr merge lp:~asomya/nova/dev
Reviewer Review Type Date Requested Status
Vish Ishaya (community) Approve
Rick Harris (community) Approve
Review via email: mp+65051@code.launchpad.net

Description of the change

Bug #796813: vmwareapi does not support distributed vswitch

The extant API assumed a standard switch network for all cases of ESX(i), was not usable when the hypervisor was added to a distributed portgroup on a virtual switch. The VM's would create a new standard switch with the same name as the dv portgroup.

Bug #796834: ESX(i) : Incorrect machine id parameters in vmx for guest_tool.py

-The machine.id string was missing required information for the guest_tool.py script to set networking in the guest VMs.
-Additionally the script crashed on Python > 2.4 due to the implicit gettext translator(_()) used.
-Added support for Ubuntu guest operating systems.

To post a comment you must log in.
Revision history for this message
Rick Harris (rconradharris) wrote :

Nice work Arvind.

Some small nits:

> 32 + # NOTE: This only works on ESXi if the port binding is
> 33 + # set to ephemeral

> 81 + # NOTE: Only works on ESXi if the portgroup binding is set to

Per HACKING, this should be NOTE(asomya):

> 40 + "get_dynamic_property",network,

PEP-8 Nit: needs a space after the comma:

  "get_dynamic_property", network,

There are a few other pep-8 nits in the code, I'd suggest running the pep8 utility on it.

> 178 +def _set_ubuntu_networking(network_details=[]):

Usually not a good idea to have a kwarg default to a list like that[1].

Better would be:

  def _set_ubuntu_networking(network_details=None):
      if not network_details:
          network_details = []

      OR

      network_details = network_details or []

[1] http://www.deadlybloodyserious.com/2008/05/default-argument-blunders/

review: Needs Fixing
Revision history for this message
Vish Ishaya (vishvananda) wrote :

172 +_ = gettext.gettext
173 +

we generally use
gettext.install('nova', unicode=1)

not sure why it was done differently here.

The NOTE(asomya) would also be valuable.

review: Needs Information
Revision history for this message
Rick Harris (rconradharris) wrote :

Thanks for the fixes, looks good.

review: Approve
Revision history for this message
Vish Ishaya (vishvananda) wrote :

looks good now.

review: Approve
Revision history for this message
OpenStack Infra (hudson-openstack) wrote :

Attempt to merge into lp:nova failed due to conflicts:

text conflict in nova/virt/vmwareapi/vmops.py

Revision history for this message
Vish Ishaya (vishvananda) wrote :

retrying

Revision history for this message
OpenStack Infra (hudson-openstack) wrote :
Download full text (185.9 KiB)

The attempt to merge lp:~asomya/nova/dev into lp:nova failed. Below is the output from the failed tests.

FloatingIpTest
    test_floating_ip_allocate OK 0.31
    test_floating_ip_associate OK 0.11
    test_floating_ip_disassociate OK 0.10
    test_floating_ip_release OK 0.10
    test_floating_ip_show OK 0.11
    test_floating_ips_list OK 0.10
    test_translate_floating_ip_view OK 0.05
FixedIpTest
    test_add_fixed_ip OK 0.08
    test_add_fixed_ip_no_network OK 0.09
    test_remove_fixed_ip OK 0.30
    test_remove_fixed_ip_no_address OK 0.07
FlavorsExtraSpecsTest
    test_create OK 0.05
    test_create_empty_body OK 0.05
    test_delete OK 0.05
    test_index OK 0.05
    test_index_no_data OK 0.05
    test_show OK 0.05
    test_show_spec_not_found OK 0.05
    test_update_item OK 0.05
    test_update_item_body_uri_mismatch OK 0.06
    test_update_item_empty_body OK 0.05
    test_update_item_too_many_keys OK 0.06
AccountsTest
    test_account_create OK 0.39
    test_account_delete OK 0.17
    test_account_update OK 0.18
    test_get_account OK 0.17
AdminAPITest
    test_admin_disabled OK 0.14
    test_admin_enabled OK 0.41
APITest
    test_exceptions_are_converted_to_faults OK 0.01
    test_malformed_json OK 0.07
    test_malformed_xml OK 0.06
Test
    test_authorize_project OK 0.11
    test_authorize_token OK 0.11
    test_authorize_user OK 0.06
    test_bad_project OK 0.35
    test_bad_token OK 0.06
    test_bad_user_bad_key OK 0.07
    test_bad_user_good_key OK 0.06
    test_no_user OK 0.06
    test_not_existing_project OK 0.10
    test_token_expiry OK 0.06
TestFunctiona...

Revision history for this message
Vish Ishaya (vishvananda) wrote :

Looks like you need to do some pep8 cleanup

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'Authors'
2--- Authors 2011-07-20 19:10:01 +0000
3+++ Authors 2011-07-25 15:24:59 +0000
4@@ -8,6 +8,7 @@
5 Anthony Young <sleepsonthefloor@gmail.com>
6 Antony Messerli <ant@openstack.org>
7 Armando Migliaccio <Armando.Migliaccio@eu.citrix.com>
8+Arvind Somya <asomya@cisco.com>
9 Bilal Akhtar <bilalakhtar@ubuntu.com>
10 Brian Lamar <brian.lamar@rackspace.com>
11 Brian Schott <bschott@isi.edu>
12
13=== modified file 'nova/virt/vmwareapi/network_utils.py'
14--- nova/virt/vmwareapi/network_utils.py 2011-03-24 16:38:31 +0000
15+++ nova/virt/vmwareapi/network_utils.py 2011-07-25 15:24:59 +0000
16@@ -45,10 +45,30 @@
17 networks = session._call_method(vim_util,
18 "get_properties_for_a_collection_of_objects",
19 "Network", vm_networks, ["summary.name"])
20- for network in networks:
21- if network.propSet[0].val == network_name:
22- return network.obj
23- return None
24+ network_obj = {}
25+ for network in vm_networks:
26+ # Get network properties
27+ if network._type == 'DistributedVirtualPortgroup':
28+ props = session._call_method(vim_util,
29+ "get_dynamic_property", network,
30+ "DistributedVirtualPortgroup", "config")
31+ # NOTE(asomya): This only works on ESXi if the port binding is
32+ # set to ephemeral
33+ if props.name == network_name:
34+ network_obj['type'] = 'DistributedVirtualPortgroup'
35+ network_obj['dvpg'] = props.key
36+ network_obj['dvsw'] = props.distributedVirtualSwitch.value
37+ else:
38+ props = session._call_method(vim_util,
39+ "get_dynamic_property", network,
40+ "Network", "summary.name")
41+ if props == network_name:
42+ network_obj['type'] = 'Network'
43+ network_obj['name'] = network_name
44+ if (len(network_obj) > 0):
45+ return network_obj
46+ else:
47+ return None
48
49
50 def get_vswitch_for_vlan_interface(session, vlan_interface):
51
52=== modified file 'nova/virt/vmwareapi/vm_util.py'
53--- nova/virt/vmwareapi/vm_util.py 2011-05-19 15:40:49 +0000
54+++ nova/virt/vmwareapi/vm_util.py 2011-07-25 15:24:59 +0000
55@@ -40,7 +40,7 @@
56
57 def get_vm_create_spec(client_factory, instance, data_store_name,
58 network_name="vmnet0",
59- os_type="otherGuest"):
60+ os_type="otherGuest", network_ref=None):
61 """Builds the VM Create spec."""
62 config_spec = client_factory.create('ns0:VirtualMachineConfigSpec')
63 config_spec.name = instance.name
64@@ -93,7 +93,8 @@
65 return virtual_device_config
66
67
68-def create_network_spec(client_factory, network_name, mac_address):
69+def create_network_spec(client_factory, network_name, mac_address,
70+ network_ref=None):
71 """
72 Builds a config spec for the addition of a new network
73 adapter to the VM.
74@@ -105,9 +106,24 @@
75 # Get the recommended card type for the VM based on the guest OS of the VM
76 net_device = client_factory.create('ns0:VirtualPCNet32')
77
78- backing = \
79- client_factory.create('ns0:VirtualEthernetCardNetworkBackingInfo')
80- backing.deviceName = network_name
81+ # NOTE(asomya): Only works on ESXi if the portgroup binding is set to
82+ # ephemeral. Invalid configuration if set to static and the NIC does
83+ # not come up on boot if set to dynamic.
84+ backing = None
85+ if (network_ref['type'] == "DistributedVirtualPortgroup"):
86+ backing_name = \
87+ 'ns0:VirtualEthernetCardDistributedVirtualPortBackingInfo'
88+ backing = \
89+ client_factory.create(backing_name)
90+ portgroup = \
91+ client_factory.create('ns0:DistributedVirtualSwitchPortConnection')
92+ portgroup.switchUuid = network_ref['dvsw']
93+ portgroup.portgroupKey = network_ref['dvpg']
94+ backing.port = portgroup
95+ else:
96+ backing = \
97+ client_factory.create('ns0:VirtualEthernetCardNetworkBackingInfo')
98+ backing.deviceName = network_name
99
100 connectable_spec = \
101 client_factory.create('ns0:VirtualDeviceConnectInfo')
102@@ -278,9 +294,11 @@
103 return config_spec
104
105
106-def get_machine_id_change_spec(client_factory, mac, ip_addr, netmask, gateway):
107+def get_machine_id_change_spec(client_factory, mac, ip_addr, netmask,
108+ gateway, broadcast, dns):
109 """Builds the machine id change config spec."""
110- machine_id_str = "%s;%s;%s;%s" % (mac, ip_addr, netmask, gateway)
111+ machine_id_str = "%s;%s;%s;%s;%s;%s" % (mac, ip_addr, netmask,
112+ gateway, broadcast, dns)
113 virtual_machine_config_spec = \
114 client_factory.create('ns0:VirtualMachineConfigSpec')
115
116
117=== modified file 'nova/virt/vmwareapi/vmops.py'
118--- nova/virt/vmwareapi/vmops.py 2011-06-03 18:34:54 +0000
119+++ nova/virt/vmwareapi/vmops.py 2011-07-25 15:24:59 +0000
120@@ -116,8 +116,9 @@
121 net_name)
122 if network_ref is None:
123 raise exception.NetworkNotFoundForBridge(bridge=net_name)
124+ return network_ref
125
126- _check_if_network_bridge_exists()
127+ network_obj = _check_if_network_bridge_exists()
128
129 def _get_datastore_ref():
130 """Get the datastore list and choose the first local storage."""
131@@ -175,8 +176,10 @@
132 vm_folder_mor, res_pool_mor = _get_vmfolder_and_res_pool_mors()
133
134 # Get the create vm config spec
135- config_spec = vm_util.get_vm_create_spec(client_factory, instance,
136- data_store_name, net_name, os_type)
137+ config_spec = vm_util.get_vm_create_spec(
138+ client_factory, instance,
139+ data_store_name, net_name, os_type,
140+ network_obj)
141
142 def _execute_create_vm():
143 """Create VM on ESX host."""
144@@ -718,13 +721,17 @@
145
146 net_mask = network["netmask"]
147 gateway = network["gateway"]
148+ broadcast = network["broadcast"]
149+ dns = network["dns"]
150+
151 addresses = db.instance_get_fixed_addresses(admin_context,
152 instance['id'])
153 ip_addr = addresses[0] if addresses else None
154
155 machine_id_chanfge_spec = \
156 vm_util.get_machine_id_change_spec(client_factory, mac_address,
157- ip_addr, net_mask, gateway)
158+ ip_addr, net_mask, gateway,
159+ broadcast, dns)
160 LOG.debug(_("Reconfiguring VM instance %(name)s to set the machine id "
161 "with ip - %(ip_addr)s") %
162 ({'name': instance.name,
163
164=== modified file 'tools/esx/guest_tool.py'
165--- tools/esx/guest_tool.py 2011-04-18 20:53:09 +0000
166+++ tools/esx/guest_tool.py 2011-07-25 15:24:59 +0000
167@@ -21,6 +21,7 @@
168 """
169
170 import array
171+import gettext
172 import logging
173 import os
174 import platform
175@@ -30,6 +31,8 @@
176 import sys
177 import time
178
179+gettext.install('nova', unicode=1)
180+
181 PLATFORM_WIN = 'win32'
182 PLATFORM_LINUX = 'linux2'
183 ARCH_32_BIT = '32bit'
184@@ -275,7 +278,8 @@
185 return final_list
186
187
188-def _set_rhel_networking(network_details=[]):
189+def _set_rhel_networking(network_details=None):
190+ network_details = network_details or []
191 all_dns_servers = []
192 for network_detail in network_details:
193 mac_address, ip_address, subnet_mask, gateway, broadcast,\
194@@ -315,6 +319,46 @@
195 _execute(['/sbin/service', 'network', 'restart'])
196
197
198+def _set_ubuntu_networking(network_details=None):
199+ network_details = network_details or []
200+ """ Set IPv4 network settings for Ubuntu """
201+ all_dns_servers = []
202+ for network_detail in network_details:
203+ mac_address, ip_address, subnet_mask, gateway, broadcast,\
204+ dns_servers = network_detail
205+ all_dns_servers.extend(dns_servers)
206+ adapter_name, current_ip_address = \
207+ _get_linux_adapter_name_and_ip_address(mac_address)
208+
209+ if adapter_name and not ip_address == current_ip_address:
210+ interface_file_name = \
211+ '/etc/network/interfaces'
212+ # Remove file
213+ os.remove(interface_file_name)
214+ # Touch file
215+ _execute(['touch', interface_file_name])
216+ interface_file = open(interface_file_name, 'w')
217+ interface_file.write('\nauto %s' % adapter_name)
218+ interface_file.write('\niface %s inet static' % adapter_name)
219+ interface_file.write('\nbroadcast %s' % broadcast)
220+ interface_file.write('\ngateway %s' % gateway)
221+ interface_file.write('\nnetmask %s' % subnet_mask)
222+ interface_file.write('\naddress %s' % ip_address)
223+ interface_file.close()
224+ if all_dns_servers:
225+ dns_file_name = "/etc/resolv.conf"
226+ os.remove(dns_file_name)
227+ _execute(['touch', dns_file_name])
228+ dns_file = open(dns_file_name, 'w')
229+ dns_file.write("; generated by OpenStack guest tools")
230+ unique_entries = _filter_duplicates(all_dns_servers)
231+ for dns_server in unique_entries:
232+ dns_file.write("\nnameserver %s" % dns_server)
233+ dns_file.close()
234+ print "\nRestarting networking....\n"
235+ _execute(['/etc/init.d/networking', 'restart'])
236+
237+
238 def _linux_set_networking():
239 """Set IP address for the Linux VM."""
240 vmware_tools_bin = None
241@@ -330,8 +374,13 @@
242 cmd = [vmware_tools_bin, '--cmd', 'machine.id.get']
243 network_details = _parse_network_details(_execute(cmd,
244 check_exit_code=False))
245- # TODO(sateesh): For other distros like ubuntu, suse, debian, BSD, etc.
246- _set_rhel_networking(network_details)
247+ # TODO(sateesh): For other distros like suse, debian, BSD, etc.
248+ if(platform.dist()[0] == 'Ubuntu'):
249+ _set_ubuntu_networking(network_details)
250+ elif (platform.dist()[0] == 'redhat'):
251+ _set_rhel_networking(network_details)
252+ else:
253+ logging.warn(_("Distro '%s' not supported") % platform.dist()[0])
254 else:
255 logging.warn(_("VMware Tools is not installed"))
256