VMWare: add power off vm before detach disk during unrescue

Non Hot Plug type disk like IDE can only be detached when the VM is power off.

Change-Id: Ib1f387a41abe2b52357854e90c2535ebb7b43f18
Close-bug: #1279199
(cherry picked from commit 1e1915aaac)
This commit is contained in:
Xiaoyan Ding 2014-02-24 16:17:46 +08:00 committed by garyk
parent 3b41c1b8b3
commit fb030283be
2 changed files with 38 additions and 10 deletions

View File

@ -1273,14 +1273,31 @@ class VMwareAPIVMTestCase(test.NoDBTestCase):
def test_unrescue(self):
self._rescue()
self.test_vm_ref = None
self.test_device_name = None
def fake_detach_disk_from_vm(*args, **kwargs):
pass
def fake_power_off_vm_ref(vm_ref):
self.test_vm_ref = vm_ref
self.assertIsNotNone(vm_ref)
self.stubs.Set(self.conn._volumeops, "detach_disk_from_vm",
fake_detach_disk_from_vm)
def fake_detach_disk_from_vm(vm_ref, instance,
device_name, destroy_disk=False):
self.test_device_name = device_name
info = self.conn.get_info(instance)
self._check_vm_info(info, power_state.SHUTDOWN)
self.conn.unrescue(self.instance, None)
with contextlib.nested(
mock.patch.object(self.conn._vmops, "_power_off_vm_ref",
side_effect=fake_power_off_vm_ref),
mock.patch.object(self.conn._volumeops, "detach_disk_from_vm",
side_effect=fake_detach_disk_from_vm),
) as (poweroff, detach):
self.conn.unrescue(self.instance, None)
poweroff.assert_called_once_with(self.test_vm_ref)
detach.assert_called_once_with(self.test_vm_ref, mock.ANY,
self.test_device_name)
self.test_vm_ref = None
self.test_device_name = None
info = self.conn.get_info({'name': 1, 'uuid': self.uuid,
'node': self.instance_node})
self._check_vm_info(info, power_state.RUNNING)

View File

@ -1159,12 +1159,26 @@ class VMwareVMOps(object):
"get_dynamic_property", vm_rescue_ref,
"VirtualMachine", "config.hardware.device")
device = vm_util.get_vmdk_volume_disk(hardware_devices, path=vmdk_path)
self._power_off_vm_ref(vm_rescue_ref)
self._volumeops.detach_disk_from_vm(vm_rescue_ref, r_instance, device)
self.destroy(r_instance, None, instance_name=instance_name)
self._power_on(instance)
def _power_off_vm_ref(self, vm_ref):
"""Power off the specifed vm.
:param vm_ref: a reference object to the VM.
"""
poweroff_task = self._session._call_method(
self._session._get_vim(),
"PowerOffVM_Task", vm_ref)
self._session._wait_for_task(poweroff_task)
def power_off(self, instance):
"""Power off the specified instance."""
"""Power off the specified instance.
:param instance: nova.objects.instance.Instance
"""
vm_ref = vm_util.get_vm_ref(self._session, instance)
pwr_state = self._session._call_method(vim_util,
@ -1173,10 +1187,7 @@ class VMwareVMOps(object):
# Only PoweredOn VMs can be powered off.
if pwr_state == "poweredOn":
LOG.debug(_("Powering off the VM"), instance=instance)
poweroff_task = self._session._call_method(
self._session._get_vim(),
"PowerOffVM_Task", vm_ref)
self._session._wait_for_task(poweroff_task)
self._power_off_vm_ref(vm_ref)
LOG.debug(_("Powered off the VM"), instance=instance)
# Raise Exception if VM is suspended
elif pwr_state == "suspended":