VMware: fix exception when multiple compute nodes are running

A number of operations in the VMwareVCDriver class first validate
that instances node is the cluster that is mapped to the compute
node. This is problematic when the compute nodes have different
configurations, for example, each compute node is mapped to a
different cluster.

In this case many operations that are just performing instance operations
will fail. This patch ensure that all instance operations that do not
require a cluster or volume will make use of the base _vmops class.
This is due to the fact that it only requires the instance details
to interface with the VC and there are no specific cluster operations.

Change-Id: I2bc38a480f2feb12ea41e7d28f80b29dd49a79b8
Closes-bug: #1345460
(cherry picked from commit 8e4a9156f4)
This commit is contained in:
Gary Kotton 2014-07-19 23:24:54 -07:00
parent 9b6699feff
commit acefbcb204
1 changed files with 27 additions and 54 deletions

View File

@ -242,24 +242,21 @@ class VMwareVCDriver(driver.ComputeDriver):
def confirm_migration(self, migration, instance, network_info):
"""Confirms a resize, destroying the source VM."""
_vmops = self._get_vmops_for_compute_node(instance['node'])
_vmops.confirm_migration(migration, instance, network_info)
self._vmops.confirm_migration(migration, instance, network_info)
def finish_revert_migration(self, context, instance, network_info,
block_device_info=None, power_on=True):
"""Finish reverting a resize, powering back on the instance."""
_vmops = self._get_vmops_for_compute_node(instance['node'])
_vmops.finish_revert_migration(context, instance, network_info,
block_device_info, power_on)
self._vmops.finish_revert_migration(context, instance, network_info,
block_device_info, power_on)
def finish_migration(self, context, migration, instance, disk_info,
network_info, image_meta, resize_instance,
block_device_info=None, power_on=True):
"""Completes a resize, turning on the migrated instance."""
_vmops = self._get_vmops_for_compute_node(instance['node'])
_vmops.finish_migration(context, migration, instance, disk_info,
network_info, image_meta, resize_instance,
block_device_info, power_on)
self._vmops.finish_migration(context, migration, instance, disk_info,
network_info, image_meta, resize_instance,
block_device_info, power_on)
def live_migration(self, context, instance, dest,
post_method, recover_method, block_migration=False,
@ -284,8 +281,7 @@ class VMwareVCDriver(driver.ComputeDriver):
"""Return link to instance's VNC console using vCenter logic."""
# vCenter does not actually run the VNC service
# itself. You must talk to the VNC host underneath vCenter.
_vmops = self._get_vmops_for_compute_node(instance['node'])
return _vmops.get_vnc_console(instance)
return self._vmops.get_vnc_console(instance)
def _update_resources(self):
"""This method creates a dictionary of VMOps, VolumeOps and VCState.
@ -464,8 +460,7 @@ class VMwareVCDriver(driver.ComputeDriver):
def get_volume_connector(self, instance):
"""Return volume connector information."""
_volumeops = self._get_volumeops_for_compute_node(instance['node'])
return _volumeops.get_volume_connector(instance)
return self._volumeops.get_volume_connector(instance)
def get_host_ip_addr(self):
"""Returns the IP address of the vCenter host."""
@ -473,14 +468,12 @@ class VMwareVCDriver(driver.ComputeDriver):
def snapshot(self, context, instance, image_id, update_task_state):
"""Create snapshot from a running VM instance."""
_vmops = self._get_vmops_for_compute_node(instance['node'])
_vmops.snapshot(context, instance, image_id, update_task_state)
self._vmops.snapshot(context, instance, image_id, update_task_state)
def reboot(self, context, instance, network_info, reboot_type,
block_device_info=None, bad_volumes_callback=None):
"""Reboot VM instance."""
_vmops = self._get_vmops_for_compute_node(instance['node'])
_vmops.reboot(instance, network_info)
self._vmops.reboot(instance, network_info)
def destroy(self, context, instance, network_info, block_device_info=None,
destroy_disks=True, migrate_data=None):
@ -492,74 +485,58 @@ class VMwareVCDriver(driver.ComputeDriver):
if not instance['node']:
return
_vmops = self._get_vmops_for_compute_node(instance['node'])
_vmops.destroy(instance, destroy_disks)
self._vmops.destroy(instance, destroy_disks)
def pause(self, instance):
"""Pause VM instance."""
_vmops = self._get_vmops_for_compute_node(instance['node'])
_vmops.pause(instance)
self._vmops.pause(instance)
def unpause(self, instance):
"""Unpause paused VM instance."""
_vmops = self._get_vmops_for_compute_node(instance['node'])
_vmops.unpause(instance)
self._vmops.unpause(instance)
def suspend(self, instance):
"""Suspend the specified instance."""
_vmops = self._get_vmops_for_compute_node(instance['node'])
_vmops.suspend(instance)
self._vmops.suspend(instance)
def resume(self, context, instance, network_info, block_device_info=None):
"""Resume the suspended VM instance."""
_vmops = self._get_vmops_for_compute_node(instance['node'])
_vmops.resume(instance)
self._vmops.resume(instance)
def rescue(self, context, instance, network_info, image_meta,
rescue_password):
"""Rescue the specified instance."""
_vmops = self._get_vmops_for_compute_node(instance.node)
_vmops.rescue(context, instance, network_info, image_meta)
self._vmops.rescue(context, instance, network_info, image_meta)
def unrescue(self, instance, network_info):
"""Unrescue the specified instance."""
_vmops = self._get_vmops_for_compute_node(instance.node)
_vmops.unrescue(instance)
self._vmops.unrescue(instance)
def power_off(self, instance, timeout=0, retry_interval=0):
"""Power off the specified instance."""
# TODO(PhilDay): Add support for timeout (clean shutdown)
_vmops = self._get_vmops_for_compute_node(instance['node'])
_vmops.power_off(instance)
self._vmops.power_off(instance)
def power_on(self, context, instance, network_info,
block_device_info=None):
"""Power on the specified instance."""
_vmops = self._get_vmops_for_compute_node(instance['node'])
_vmops.power_on(instance)
self._vmops.power_on(instance)
def poll_rebooting_instances(self, timeout, instances):
"""Poll for rebooting instances."""
for instance in instances:
_vmops = self._get_vmops_for_compute_node(instance['node'])
_vmops.poll_rebooting_instances(timeout, [instance])
self._vmops.poll_rebooting_instances(timeout, instances)
def get_info(self, instance):
"""Return info about the VM instance."""
_vmops = self._get_vmops_for_compute_node(instance['node'])
return _vmops.get_info(instance)
return self._vmops.get_info(instance)
def get_diagnostics(self, instance):
"""Return data about VM diagnostics."""
_vmops = self._get_vmops_for_compute_node(instance['node'])
data = _vmops.get_diagnostics(instance)
return data
return self._vmops.get_diagnostics(instance)
def get_instance_diagnostics(self, instance):
"""Return data about VM diagnostics."""
_vmops = self._get_vmops_for_compute_node(instance['node'])
data = _vmops.get_instance_diagnostics(instance)
return data
return self._vmops.get_instance_diagnostics(instance)
def host_power_action(self, host, action):
"""Host operations not supported by VC driver.
@ -592,8 +569,7 @@ class VMwareVCDriver(driver.ComputeDriver):
def inject_network_info(self, instance, nw_info):
"""inject network info for specified instance."""
_vmops = self._get_vmops_for_compute_node(instance['node'])
_vmops.inject_network_info(instance, nw_info)
self._vmops.inject_network_info(instance, nw_info)
def manage_image_cache(self, context, all_instances):
"""Manage the local cache of images."""
@ -616,18 +592,15 @@ class VMwareVCDriver(driver.ComputeDriver):
def instance_exists(self, instance):
"""Efficient override of base instance_exists method."""
_vmops = self._get_vmops_for_compute_node(instance['node'])
return _vmops.instance_exists(instance)
return self._vmops.instance_exists(instance)
def attach_interface(self, instance, image_meta, vif):
"""Attach an interface to the instance."""
_vmops = self._get_vmops_for_compute_node(instance.node)
_vmops.attach_interface(instance, image_meta, vif)
self._vmops.attach_interface(instance, image_meta, vif)
def detach_interface(self, instance, vif):
"""Detach an interface from the instance."""
_vmops = self._get_vmops_for_compute_node(instance.node)
_vmops.detach_interface(instance, vif)
self._vmops.detach_interface(instance, vif)
class VMwareAPISession(api.VMwareAPISession):