Merge lp:~sateesh-chodapuneedi/nova/esx-multi-nic into lp:~hudson-openstack/nova/trunk
- esx-multi-nic
- Merge into trunk
Status: | Merged | ||||||||
---|---|---|---|---|---|---|---|---|---|
Approved by: | Dan Prince | ||||||||
Approved revision: | 1527 | ||||||||
Merged at revision: | 1568 | ||||||||
Proposed branch: | lp:~sateesh-chodapuneedi/nova/esx-multi-nic | ||||||||
Merge into: | lp:~hudson-openstack/nova/trunk | ||||||||
Diff against target: |
440 lines (+127/-112) 6 files modified
nova/tests/vmwareapi/stubs.py (+0/-2) nova/virt/vmwareapi/fake.py (+1/-1) nova/virt/vmwareapi/vif.py (+11/-16) nova/virt/vmwareapi/vm_util.py (+12/-16) nova/virt/vmwareapi/vmops.py (+63/-47) tools/esx/guest_tool.py (+40/-30) |
||||||||
To merge this branch: | bzr merge lp:~sateesh-chodapuneedi/nova/esx-multi-nic | ||||||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Dan Prince (community) | Approve | ||
Vish Ishaya (community) | Approve | ||
Review via email:
|
Commit message
Description of the change
Multi-NIC support for vmwareapi virt driver in nova.
Does injection of Multi-NIC information to instances with Operating system flavors Ubuntu, Windows and RHEL.
vmwareapi virt driver now relies on calls to network manager instead of nova db calls for network configuration information of instance.
Re-oranized VMWareVlanBridg
Added check for flat_inject flag before attempting an inject operation.
This branch resolves the following bugs:
Bug #831497 in OpenStack Compute (nova): "Instance spawn operation fails on ESXi compute node"
https:/
Bug #839383 in OpenStack Compute (nova): "ESX(i) VIFs and mac addresses"
https:/
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Sateesh (sateesh-chodapuneedi) wrote : | # |
@Vish thanks for the review.
> 63 - bridge_interface = network[
> 64 + vlan_interface = FLAGS.vmwareapi
>
> can we just use the global vlan interface here?
I choose to use separate flag because vlan_interface is not being used in the current code base (revision 1526), also post multi-nic nova code started using bridge_interface in networks table rather than depending on this flag. From the information I have, it seems to me that this flag is going to become stale. So I thought of having a separate flag specific vmwareapi virt driver which deals with it's specific case. Even if vlan_interface flag gets removed no functionality breakage occur in vmwareapi virt driver. So trying to keep this flag modular (or module specific).
Also ESX(i) names it NIC with prefix 'vmnic', different from other systems that use prefix 'eth'. So I thought if we classify the flag by it's value, it becomes specific to vmware subset.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Vish Ishaya (vishvananda) wrote : | # |
We were actually planning on adding the flag back as an override. It is possible that the interface specified in the table is incorrect for some hosts. For example if you have two hosts, one using eth0 and the other using eth1. But this is a minor issue that can be fixed later. I'm happy leaving this as is for now.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Dan Prince (dan-prince) wrote : | # |
Looks good to me.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Sateesh (sateesh-chodapuneedi) wrote : | # |
Thanks Vish and Dan for your reviews.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Sateesh (sateesh-chodapuneedi) wrote : | # |
Thanks Vish and Dan for your reviews.
~Sateesh
Preview Diff
1 | === modified file 'nova/tests/vmwareapi/stubs.py' | |||
2 | --- nova/tests/vmwareapi/stubs.py 2011-07-27 00:40:50 +0000 | |||
3 | +++ nova/tests/vmwareapi/stubs.py 2011-09-05 07:38:25 +0000 | |||
4 | @@ -47,7 +47,5 @@ | |||
5 | 47 | stubs.Set(vmware_images, 'upload_image', fake.fake_upload_image) | 47 | stubs.Set(vmware_images, 'upload_image', fake.fake_upload_image) |
6 | 48 | stubs.Set(vmwareapi_conn.VMWareAPISession, "_get_vim_object", | 48 | stubs.Set(vmwareapi_conn.VMWareAPISession, "_get_vim_object", |
7 | 49 | fake_get_vim_object) | 49 | fake_get_vim_object) |
8 | 50 | stubs.Set(vmwareapi_conn.VMWareAPISession, "_get_vim_object", | ||
9 | 51 | fake_get_vim_object) | ||
10 | 52 | stubs.Set(vmwareapi_conn.VMWareAPISession, "_is_vim_object", | 50 | stubs.Set(vmwareapi_conn.VMWareAPISession, "_is_vim_object", |
11 | 53 | fake_is_vim_object) | 51 | fake_is_vim_object) |
12 | 54 | 52 | ||
13 | === modified file 'nova/virt/vmwareapi/fake.py' | |||
14 | --- nova/virt/vmwareapi/fake.py 2011-07-27 00:40:50 +0000 | |||
15 | +++ nova/virt/vmwareapi/fake.py 2011-09-05 07:38:25 +0000 | |||
16 | @@ -409,7 +409,7 @@ | |||
17 | 409 | 409 | ||
18 | 410 | def fake_get_network(*args, **kwargs): | 410 | def fake_get_network(*args, **kwargs): |
19 | 411 | """Fake get network.""" | 411 | """Fake get network.""" |
21 | 412 | return [{'type': 'fake'}] | 412 | return {'type': 'fake'} |
22 | 413 | 413 | ||
23 | 414 | 414 | ||
24 | 415 | def fake_fetch_image(image, instance, **kwargs): | 415 | def fake_fetch_image(image, instance, **kwargs): |
25 | 416 | 416 | ||
26 | === modified file 'nova/virt/vmwareapi/vif.py' | |||
27 | --- nova/virt/vmwareapi/vif.py 2011-08-03 18:49:14 +0000 | |||
28 | +++ nova/virt/vmwareapi/vif.py 2011-09-05 07:38:25 +0000 | |||
29 | @@ -17,42 +17,35 @@ | |||
30 | 17 | 17 | ||
31 | 18 | """VIF drivers for VMWare.""" | 18 | """VIF drivers for VMWare.""" |
32 | 19 | 19 | ||
33 | 20 | from nova import db | ||
34 | 21 | from nova import exception | 20 | from nova import exception |
35 | 22 | from nova import flags | 21 | from nova import flags |
36 | 23 | from nova import log as logging | 22 | from nova import log as logging |
37 | 24 | from nova import utils | ||
38 | 25 | from nova.virt.vif import VIFDriver | 23 | from nova.virt.vif import VIFDriver |
39 | 26 | from nova.virt.vmwareapi_conn import VMWareAPISession | ||
40 | 27 | from nova.virt.vmwareapi import network_utils | 24 | from nova.virt.vmwareapi import network_utils |
41 | 28 | 25 | ||
42 | 29 | 26 | ||
43 | 30 | LOG = logging.getLogger("nova.virt.vmwareapi.vif") | 27 | LOG = logging.getLogger("nova.virt.vmwareapi.vif") |
44 | 31 | 28 | ||
45 | 32 | FLAGS = flags.FLAGS | 29 | FLAGS = flags.FLAGS |
46 | 30 | FLAGS['vmwareapi_vlan_interface'].SetDefault('vmnic0') | ||
47 | 33 | 31 | ||
48 | 34 | 32 | ||
49 | 35 | class VMWareVlanBridgeDriver(VIFDriver): | 33 | class VMWareVlanBridgeDriver(VIFDriver): |
50 | 36 | """VIF Driver to setup bridge/VLAN networking using VMWare API.""" | 34 | """VIF Driver to setup bridge/VLAN networking using VMWare API.""" |
51 | 37 | 35 | ||
52 | 38 | def plug(self, instance, network, mapping): | 36 | def plug(self, instance, network, mapping): |
53 | 37 | """Plug the VIF to specified instance using information passed. | ||
54 | 38 | Currently we are plugging the VIF(s) during instance creation itself. | ||
55 | 39 | We can use this method when we add support to add additional NIC to | ||
56 | 40 | an existing instance.""" | ||
57 | 41 | pass | ||
58 | 42 | |||
59 | 43 | def ensure_vlan_bridge(self, session, network): | ||
60 | 39 | """Create a vlan and bridge unless they already exist.""" | 44 | """Create a vlan and bridge unless they already exist.""" |
61 | 40 | vlan_num = network['vlan'] | 45 | vlan_num = network['vlan'] |
62 | 41 | bridge = network['bridge'] | 46 | bridge = network['bridge'] |
64 | 42 | bridge_interface = network['bridge_interface'] | 47 | vlan_interface = FLAGS.vmwareapi_vlan_interface |
65 | 43 | 48 | ||
66 | 44 | # Open vmwareapi session | ||
67 | 45 | host_ip = FLAGS.vmwareapi_host_ip | ||
68 | 46 | host_username = FLAGS.vmwareapi_host_username | ||
69 | 47 | host_password = FLAGS.vmwareapi_host_password | ||
70 | 48 | if not host_ip or host_username is None or host_password is None: | ||
71 | 49 | raise Exception(_('Must specify vmwareapi_host_ip, ' | ||
72 | 50 | 'vmwareapi_host_username ' | ||
73 | 51 | 'and vmwareapi_host_password to use ' | ||
74 | 52 | 'connection_type=vmwareapi')) | ||
75 | 53 | session = VMWareAPISession(host_ip, host_username, host_password, | ||
76 | 54 | FLAGS.vmwareapi_api_retry_count) | ||
77 | 55 | vlan_interface = bridge_interface | ||
78 | 56 | # Check if the vlan_interface physical network adapter exists on the | 49 | # Check if the vlan_interface physical network adapter exists on the |
79 | 57 | # host. | 50 | # host. |
80 | 58 | if not network_utils.check_if_vlan_interface_exists(session, | 51 | if not network_utils.check_if_vlan_interface_exists(session, |
81 | @@ -92,4 +85,6 @@ | |||
82 | 92 | pgroup=pg_vlanid) | 85 | pgroup=pg_vlanid) |
83 | 93 | 86 | ||
84 | 94 | def unplug(self, instance, network, mapping): | 87 | def unplug(self, instance, network, mapping): |
85 | 88 | """Cleanup operations like deleting port group if no instance | ||
86 | 89 | is associated with it.""" | ||
87 | 95 | pass | 90 | pass |
88 | 96 | 91 | ||
89 | === modified file 'nova/virt/vmwareapi/vm_util.py' | |||
90 | --- nova/virt/vmwareapi/vm_util.py 2011-07-27 00:40:50 +0000 | |||
91 | +++ nova/virt/vmwareapi/vm_util.py 2011-09-05 07:38:25 +0000 | |||
92 | @@ -39,8 +39,7 @@ | |||
93 | 39 | 39 | ||
94 | 40 | 40 | ||
95 | 41 | def get_vm_create_spec(client_factory, instance, data_store_name, | 41 | def get_vm_create_spec(client_factory, instance, data_store_name, |
98 | 42 | network_name="vmnet0", | 42 | vif_infos, os_type="otherGuest"): |
97 | 43 | os_type="otherGuest", network_ref=None): | ||
99 | 44 | """Builds the VM Create spec.""" | 43 | """Builds the VM Create spec.""" |
100 | 45 | config_spec = client_factory.create('ns0:VirtualMachineConfigSpec') | 44 | config_spec = client_factory.create('ns0:VirtualMachineConfigSpec') |
101 | 46 | config_spec.name = instance.name | 45 | config_spec.name = instance.name |
102 | @@ -61,14 +60,12 @@ | |||
103 | 61 | config_spec.numCPUs = int(instance.vcpus) | 60 | config_spec.numCPUs = int(instance.vcpus) |
104 | 62 | config_spec.memoryMB = int(instance.memory_mb) | 61 | config_spec.memoryMB = int(instance.memory_mb) |
105 | 63 | 62 | ||
114 | 64 | mac_address = None | 63 | vif_spec_list = [] |
115 | 65 | if instance['mac_addresses']: | 64 | for vif_info in vif_infos: |
116 | 66 | mac_address = instance['mac_addresses'][0]['address'] | 65 | vif_spec = create_network_spec(client_factory, vif_info) |
117 | 67 | 66 | vif_spec_list.append(vif_spec) | |
118 | 68 | nic_spec = create_network_spec(client_factory, | 67 | |
119 | 69 | network_name, mac_address) | 68 | device_config_spec = vif_spec_list |
112 | 70 | |||
113 | 71 | device_config_spec = [nic_spec] | ||
120 | 72 | 69 | ||
121 | 73 | config_spec.deviceChange = device_config_spec | 70 | config_spec.deviceChange = device_config_spec |
122 | 74 | return config_spec | 71 | return config_spec |
123 | @@ -93,8 +90,7 @@ | |||
124 | 93 | return virtual_device_config | 90 | return virtual_device_config |
125 | 94 | 91 | ||
126 | 95 | 92 | ||
129 | 96 | def create_network_spec(client_factory, network_name, mac_address, | 93 | def create_network_spec(client_factory, vif_info): |
128 | 97 | network_ref=None): | ||
130 | 98 | """ | 94 | """ |
131 | 99 | Builds a config spec for the addition of a new network | 95 | Builds a config spec for the addition of a new network |
132 | 100 | adapter to the VM. | 96 | adapter to the VM. |
133 | @@ -109,6 +105,9 @@ | |||
134 | 109 | # NOTE(asomya): Only works on ESXi if the portgroup binding is set to | 105 | # NOTE(asomya): Only works on ESXi if the portgroup binding is set to |
135 | 110 | # ephemeral. Invalid configuration if set to static and the NIC does | 106 | # ephemeral. Invalid configuration if set to static and the NIC does |
136 | 111 | # not come up on boot if set to dynamic. | 107 | # not come up on boot if set to dynamic. |
137 | 108 | network_ref = vif_info['network_ref'] | ||
138 | 109 | network_name = vif_info['network_name'] | ||
139 | 110 | mac_address = vif_info['mac_address'] | ||
140 | 112 | backing = None | 111 | backing = None |
141 | 113 | if (network_ref and | 112 | if (network_ref and |
142 | 114 | network_ref['type'] == "DistributedVirtualPortgroup"): | 113 | network_ref['type'] == "DistributedVirtualPortgroup"): |
143 | @@ -295,11 +294,8 @@ | |||
144 | 295 | return config_spec | 294 | return config_spec |
145 | 296 | 295 | ||
146 | 297 | 296 | ||
149 | 298 | def get_machine_id_change_spec(client_factory, mac, ip_addr, netmask, | 297 | def get_machine_id_change_spec(client_factory, machine_id_str): |
148 | 299 | gateway, broadcast, dns): | ||
150 | 300 | """Builds the machine id change config spec.""" | 298 | """Builds the machine id change config spec.""" |
151 | 301 | machine_id_str = "%s;%s;%s;%s;%s;%s" % (mac, ip_addr, netmask, | ||
152 | 302 | gateway, broadcast, dns) | ||
153 | 303 | virtual_machine_config_spec = \ | 299 | virtual_machine_config_spec = \ |
154 | 304 | client_factory.create('ns0:VirtualMachineConfigSpec') | 300 | client_factory.create('ns0:VirtualMachineConfigSpec') |
155 | 305 | 301 | ||
156 | 306 | 302 | ||
157 | === modified file 'nova/virt/vmwareapi/vmops.py' | |||
158 | --- nova/virt/vmwareapi/vmops.py 2011-07-29 21:58:27 +0000 | |||
159 | +++ nova/virt/vmwareapi/vmops.py 2011-09-05 07:38:25 +0000 | |||
160 | @@ -27,7 +27,6 @@ | |||
161 | 27 | import uuid | 27 | import uuid |
162 | 28 | 28 | ||
163 | 29 | from nova import context as nova_context | 29 | from nova import context as nova_context |
164 | 30 | from nova import db | ||
165 | 31 | from nova import exception | 30 | from nova import exception |
166 | 32 | from nova import flags | 31 | from nova import flags |
167 | 33 | from nova import log as logging | 32 | from nova import log as logging |
168 | @@ -111,22 +110,6 @@ | |||
169 | 111 | client_factory = self._session._get_vim().client.factory | 110 | client_factory = self._session._get_vim().client.factory |
170 | 112 | service_content = self._session._get_vim().get_service_content() | 111 | service_content = self._session._get_vim().get_service_content() |
171 | 113 | 112 | ||
172 | 114 | network = db.network_get_by_instance(nova_context.get_admin_context(), | ||
173 | 115 | instance['id']) | ||
174 | 116 | |||
175 | 117 | net_name = network['bridge'] | ||
176 | 118 | |||
177 | 119 | def _check_if_network_bridge_exists(): | ||
178 | 120 | network_ref = \ | ||
179 | 121 | network_utils.get_network_with_the_name(self._session, | ||
180 | 122 | net_name) | ||
181 | 123 | if network_ref is None: | ||
182 | 124 | raise exception.NetworkNotFoundForBridge(bridge=net_name) | ||
183 | 125 | return network_ref | ||
184 | 126 | |||
185 | 127 | self.plug_vifs(instance, network_info) | ||
186 | 128 | network_obj = _check_if_network_bridge_exists() | ||
187 | 129 | |||
188 | 130 | def _get_datastore_ref(): | 113 | def _get_datastore_ref(): |
189 | 131 | """Get the datastore list and choose the first local storage.""" | 114 | """Get the datastore list and choose the first local storage.""" |
190 | 132 | data_stores = self._session._call_method(vim_util, "get_objects", | 115 | data_stores = self._session._call_method(vim_util, "get_objects", |
191 | @@ -182,11 +165,36 @@ | |||
192 | 182 | 165 | ||
193 | 183 | vm_folder_mor, res_pool_mor = _get_vmfolder_and_res_pool_mors() | 166 | vm_folder_mor, res_pool_mor = _get_vmfolder_and_res_pool_mors() |
194 | 184 | 167 | ||
195 | 168 | def _check_if_network_bridge_exists(network_name): | ||
196 | 169 | network_ref = \ | ||
197 | 170 | network_utils.get_network_with_the_name(self._session, | ||
198 | 171 | network_name) | ||
199 | 172 | if network_ref is None: | ||
200 | 173 | raise exception.NetworkNotFoundForBridge(bridge=network_name) | ||
201 | 174 | return network_ref | ||
202 | 175 | |||
203 | 176 | def _get_vif_infos(): | ||
204 | 177 | vif_infos = [] | ||
205 | 178 | for (network, mapping) in network_info: | ||
206 | 179 | mac_address = mapping['mac'] | ||
207 | 180 | network_name = network['bridge'] | ||
208 | 181 | if mapping.get('should_create_vlan'): | ||
209 | 182 | network_ref = self._vif_driver.ensure_vlan_bridge( | ||
210 | 183 | self._session, network) | ||
211 | 184 | else: | ||
212 | 185 | network_ref = _check_if_network_bridge_exists(network_name) | ||
213 | 186 | vif_infos.append({'network_name': network_name, | ||
214 | 187 | 'mac_address': mac_address, | ||
215 | 188 | 'network_ref': network_ref, | ||
216 | 189 | }) | ||
217 | 190 | return vif_infos | ||
218 | 191 | |||
219 | 192 | vif_infos = _get_vif_infos() | ||
220 | 193 | |||
221 | 185 | # Get the create vm config spec | 194 | # Get the create vm config spec |
222 | 186 | config_spec = vm_util.get_vm_create_spec( | 195 | config_spec = vm_util.get_vm_create_spec( |
223 | 187 | client_factory, instance, | 196 | client_factory, instance, |
226 | 188 | data_store_name, net_name, os_type, | 197 | data_store_name, vif_infos, os_type) |
225 | 189 | network_obj) | ||
227 | 190 | 198 | ||
228 | 191 | def _execute_create_vm(): | 199 | def _execute_create_vm(): |
229 | 192 | """Create VM on ESX host.""" | 200 | """Create VM on ESX host.""" |
230 | @@ -204,8 +212,10 @@ | |||
231 | 204 | 212 | ||
232 | 205 | _execute_create_vm() | 213 | _execute_create_vm() |
233 | 206 | 214 | ||
236 | 207 | # Set the machine id for the VM for setting the IP | 215 | # Set the machine.id parameter of the instance to inject |
237 | 208 | self._set_machine_id(client_factory, instance) | 216 | # the NIC configuration inside the VM |
238 | 217 | if FLAGS.flat_injected: | ||
239 | 218 | self._set_machine_id(client_factory, instance, network_info) | ||
240 | 209 | 219 | ||
241 | 210 | # Naming the VM files in correspondence with the VM instance name | 220 | # Naming the VM files in correspondence with the VM instance name |
242 | 211 | # The flat vmdk file name | 221 | # The flat vmdk file name |
243 | @@ -716,39 +726,45 @@ | |||
244 | 716 | """Return link to instance's ajax console.""" | 726 | """Return link to instance's ajax console.""" |
245 | 717 | return 'http://fakeajaxconsole/fake_url' | 727 | return 'http://fakeajaxconsole/fake_url' |
246 | 718 | 728 | ||
253 | 719 | def _set_machine_id(self, client_factory, instance): | 729 | def _set_machine_id(self, client_factory, instance, network_info): |
254 | 720 | """ | 730 | """ |
255 | 721 | Set the machine id of the VM for guest tools to pick up and change | 731 | Set the machine id of the VM for guest tools to pick up and reconfigure |
256 | 722 | the IP. | 732 | the network interfaces. |
257 | 723 | """ | 733 | """ |
252 | 724 | admin_context = nova_context.get_admin_context() | ||
258 | 725 | vm_ref = self._get_vm_ref_from_the_name(instance.name) | 734 | vm_ref = self._get_vm_ref_from_the_name(instance.name) |
259 | 726 | if vm_ref is None: | 735 | if vm_ref is None: |
260 | 727 | raise exception.InstanceNotFound(instance_id=instance.id) | 736 | raise exception.InstanceNotFound(instance_id=instance.id) |
276 | 728 | network = db.network_get_by_instance(nova_context.get_admin_context(), | 737 | |
277 | 729 | instance['id']) | 738 | machine_id_str = '' |
278 | 730 | mac_address = None | 739 | for (network, info) in network_info: |
279 | 731 | if instance['mac_addresses']: | 740 | # TODO(vish): add support for dns2 |
280 | 732 | mac_address = instance['mac_addresses'][0]['address'] | 741 | # TODO(sateesh): add support for injection of ipv6 configuration |
281 | 733 | 742 | ip_v4 = ip_v6 = None | |
282 | 734 | net_mask = network["netmask"] | 743 | if 'ips' in info and len(info['ips']) > 0: |
283 | 735 | gateway = network["gateway"] | 744 | ip_v4 = info['ips'][0] |
284 | 736 | broadcast = network["broadcast"] | 745 | if 'ip6s' in info and len(info['ip6s']) > 0: |
285 | 737 | # TODO(vish): add support for dns2 | 746 | ip_v6 = info['ip6s'][0] |
286 | 738 | dns = network["dns1"] | 747 | if len(info['dns']) > 0: |
287 | 739 | 748 | dns = info['dns'][0] | |
288 | 740 | addresses = db.instance_get_fixed_addresses(admin_context, | 749 | else: |
289 | 741 | instance['id']) | 750 | dns = '' |
290 | 742 | ip_addr = addresses[0] if addresses else None | 751 | |
291 | 752 | interface_str = "%s;%s;%s;%s;%s;%s" % \ | ||
292 | 753 | (info['mac'], | ||
293 | 754 | ip_v4 and ip_v4['ip'] or '', | ||
294 | 755 | ip_v4 and ip_v4['netmask'] or '', | ||
295 | 756 | info['gateway'], | ||
296 | 757 | info['broadcast'], | ||
297 | 758 | dns) | ||
298 | 759 | machine_id_str = machine_id_str + interface_str + '#' | ||
299 | 743 | 760 | ||
300 | 744 | machine_id_change_spec = \ | 761 | machine_id_change_spec = \ |
304 | 745 | vm_util.get_machine_id_change_spec(client_factory, mac_address, | 762 | vm_util.get_machine_id_change_spec(client_factory, machine_id_str) |
305 | 746 | ip_addr, net_mask, gateway, | 763 | |
303 | 747 | broadcast, dns) | ||
306 | 748 | LOG.debug(_("Reconfiguring VM instance %(name)s to set the machine id " | 764 | LOG.debug(_("Reconfiguring VM instance %(name)s to set the machine id " |
307 | 749 | "with ip - %(ip_addr)s") % | 765 | "with ip - %(ip_addr)s") % |
308 | 750 | ({'name': instance.name, | 766 | ({'name': instance.name, |
310 | 751 | 'ip_addr': ip_addr})) | 767 | 'ip_addr': ip_v4['ip']})) |
311 | 752 | reconfig_task = self._session._call_method(self._session._get_vim(), | 768 | reconfig_task = self._session._call_method(self._session._get_vim(), |
312 | 753 | "ReconfigVM_Task", vm_ref, | 769 | "ReconfigVM_Task", vm_ref, |
313 | 754 | spec=machine_id_change_spec) | 770 | spec=machine_id_change_spec) |
314 | @@ -756,7 +772,7 @@ | |||
315 | 756 | LOG.debug(_("Reconfigured VM instance %(name)s to set the machine id " | 772 | LOG.debug(_("Reconfigured VM instance %(name)s to set the machine id " |
316 | 757 | "with ip - %(ip_addr)s") % | 773 | "with ip - %(ip_addr)s") % |
317 | 758 | ({'name': instance.name, | 774 | ({'name': instance.name, |
319 | 759 | 'ip_addr': ip_addr})) | 775 | 'ip_addr': ip_v4['ip']})) |
320 | 760 | 776 | ||
321 | 761 | def _get_datacenter_name_and_ref(self): | 777 | def _get_datacenter_name_and_ref(self): |
322 | 762 | """Get the datacenter name and the reference.""" | 778 | """Get the datacenter name and the reference.""" |
323 | 763 | 779 | ||
324 | === modified file 'tools/esx/guest_tool.py' | |||
325 | --- tools/esx/guest_tool.py 2011-06-27 18:41:07 +0000 | |||
326 | +++ tools/esx/guest_tool.py 2011-09-05 07:38:25 +0000 | |||
327 | @@ -81,28 +81,34 @@ | |||
328 | 81 | 81 | ||
329 | 82 | def _parse_network_details(machine_id): | 82 | def _parse_network_details(machine_id): |
330 | 83 | """ | 83 | """ |
334 | 84 | Parse the machine.id field to get MAC, IP, Netmask and Gateway fields | 84 | Parse the machine_id to get MAC, IP, Netmask and Gateway fields per NIC. |
335 | 85 | machine.id is of the form MAC;IP;Netmask;Gateway;Broadcast;DNS1,DNS2 | 85 | machine_id is of the form ('NIC_record#NIC_record#', '') |
336 | 86 | where ';' is the separator. | 86 | Each of the NIC will have record NIC_record in the form |
337 | 87 | 'MAC;IP;Netmask;Gateway;Broadcast;DNS' where ';' is field separator. | ||
338 | 88 | Each record is separated by '#' from next record. | ||
339 | 87 | """ | 89 | """ |
340 | 90 | logging.debug(_("Received machine_id from vmtools : %s") % machine_id[0]) | ||
341 | 88 | network_details = [] | 91 | network_details = [] |
342 | 89 | if machine_id[1].strip() == "1": | 92 | if machine_id[1].strip() == "1": |
343 | 90 | pass | 93 | pass |
344 | 91 | else: | 94 | else: |
359 | 92 | network_info_list = machine_id[0].split(';') | 95 | for machine_id_str in machine_id[0].split('#'): |
360 | 93 | assert len(network_info_list) % 6 == 0 | 96 | network_info_list = machine_id_str.split(';') |
361 | 94 | no_grps = len(network_info_list) / 6 | 97 | if len(network_info_list) % 6 != 0: |
362 | 95 | i = 0 | 98 | break |
363 | 96 | while i < no_grps: | 99 | no_grps = len(network_info_list) / 6 |
364 | 97 | k = i * 6 | 100 | i = 0 |
365 | 98 | network_details.append(( | 101 | while i < no_grps: |
366 | 99 | network_info_list[k].strip().lower(), | 102 | k = i * 6 |
367 | 100 | network_info_list[k + 1].strip(), | 103 | network_details.append(( |
368 | 101 | network_info_list[k + 2].strip(), | 104 | network_info_list[k].strip().lower(), |
369 | 102 | network_info_list[k + 3].strip(), | 105 | network_info_list[k + 1].strip(), |
370 | 103 | network_info_list[k + 4].strip(), | 106 | network_info_list[k + 2].strip(), |
371 | 104 | network_info_list[k + 5].strip().split(','))) | 107 | network_info_list[k + 3].strip(), |
372 | 105 | i += 1 | 108 | network_info_list[k + 4].strip(), |
373 | 109 | network_info_list[k + 5].strip().split(','))) | ||
374 | 110 | i += 1 | ||
375 | 111 | logging.debug(_("NIC information from vmtools : %s") % network_details) | ||
376 | 106 | return network_details | 112 | return network_details |
377 | 107 | 113 | ||
378 | 108 | 114 | ||
379 | @@ -279,6 +285,7 @@ | |||
380 | 279 | 285 | ||
381 | 280 | 286 | ||
382 | 281 | def _set_rhel_networking(network_details=None): | 287 | def _set_rhel_networking(network_details=None): |
383 | 288 | """Set IPv4 network settings for RHEL distros.""" | ||
384 | 282 | network_details = network_details or [] | 289 | network_details = network_details or [] |
385 | 283 | all_dns_servers = [] | 290 | all_dns_servers = [] |
386 | 284 | for network_detail in network_details: | 291 | for network_detail in network_details: |
387 | @@ -320,31 +327,33 @@ | |||
388 | 320 | 327 | ||
389 | 321 | 328 | ||
390 | 322 | def _set_ubuntu_networking(network_details=None): | 329 | def _set_ubuntu_networking(network_details=None): |
391 | 330 | """Set IPv4 network settings for Ubuntu.""" | ||
392 | 323 | network_details = network_details or [] | 331 | network_details = network_details or [] |
393 | 324 | """ Set IPv4 network settings for Ubuntu """ | ||
394 | 325 | all_dns_servers = [] | 332 | all_dns_servers = [] |
396 | 326 | for network_detail in network_details: | 333 | interface_file_name = '/etc/network/interfaces' |
397 | 334 | # Remove file | ||
398 | 335 | os.remove(interface_file_name) | ||
399 | 336 | # Touch file | ||
400 | 337 | _execute(['touch', interface_file_name]) | ||
401 | 338 | interface_file = open(interface_file_name, 'w') | ||
402 | 339 | for device, network_detail in enumerate(network_details): | ||
403 | 327 | mac_address, ip_address, subnet_mask, gateway, broadcast,\ | 340 | mac_address, ip_address, subnet_mask, gateway, broadcast,\ |
404 | 328 | dns_servers = network_detail | 341 | dns_servers = network_detail |
405 | 329 | all_dns_servers.extend(dns_servers) | 342 | all_dns_servers.extend(dns_servers) |
406 | 330 | adapter_name, current_ip_address = \ | 343 | adapter_name, current_ip_address = \ |
407 | 331 | _get_linux_adapter_name_and_ip_address(mac_address) | 344 | _get_linux_adapter_name_and_ip_address(mac_address) |
408 | 332 | 345 | ||
417 | 333 | if adapter_name and not ip_address == current_ip_address: | 346 | if adapter_name: |
410 | 334 | interface_file_name = \ | ||
411 | 335 | '/etc/network/interfaces' | ||
412 | 336 | # Remove file | ||
413 | 337 | os.remove(interface_file_name) | ||
414 | 338 | # Touch file | ||
415 | 339 | _execute(['touch', interface_file_name]) | ||
416 | 340 | interface_file = open(interface_file_name, 'w') | ||
418 | 341 | interface_file.write('\nauto %s' % adapter_name) | 347 | interface_file.write('\nauto %s' % adapter_name) |
419 | 342 | interface_file.write('\niface %s inet static' % adapter_name) | 348 | interface_file.write('\niface %s inet static' % adapter_name) |
420 | 343 | interface_file.write('\nbroadcast %s' % broadcast) | 349 | interface_file.write('\nbroadcast %s' % broadcast) |
421 | 344 | interface_file.write('\ngateway %s' % gateway) | 350 | interface_file.write('\ngateway %s' % gateway) |
422 | 345 | interface_file.write('\nnetmask %s' % subnet_mask) | 351 | interface_file.write('\nnetmask %s' % subnet_mask) |
425 | 346 | interface_file.write('\naddress %s' % ip_address) | 352 | interface_file.write('\naddress %s\n' % ip_address) |
426 | 347 | interface_file.close() | 353 | logging.debug(_("Successfully configured NIC %d with " |
427 | 354 | "NIC info %s") % (device, network_detail)) | ||
428 | 355 | interface_file.close() | ||
429 | 356 | |||
430 | 348 | if all_dns_servers: | 357 | if all_dns_servers: |
431 | 349 | dns_file_name = "/etc/resolv.conf" | 358 | dns_file_name = "/etc/resolv.conf" |
432 | 350 | os.remove(dns_file_name) | 359 | os.remove(dns_file_name) |
433 | @@ -355,7 +364,8 @@ | |||
434 | 355 | for dns_server in unique_entries: | 364 | for dns_server in unique_entries: |
435 | 356 | dns_file.write("\nnameserver %s" % dns_server) | 365 | dns_file.write("\nnameserver %s" % dns_server) |
436 | 357 | dns_file.close() | 366 | dns_file.close() |
438 | 358 | print "\nRestarting networking....\n" | 367 | |
439 | 368 | logging.debug(_("Restarting networking....\n")) | ||
440 | 359 | _execute(['/etc/init.d/networking', 'restart']) | 369 | _execute(['/etc/init.d/networking', 'restart']) |
441 | 360 | 370 | ||
442 | 361 | 371 |
Awesome work on this! It will be great to have esx working properly again. Minor nit:
63 - bridge_interface = network[ 'bridge_ interface' ] _vlan_interface
64 + vlan_interface = FLAGS.vmwareapi
can we just use the global vlan interface here?