From fb030283bed9e41a0343581fa21b81b2ebb07f15 Mon Sep 17 00:00:00 2001 From: Xiaoyan Ding Date: Mon, 24 Feb 2014 16:17:46 +0800 Subject: [PATCH] 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 1e1915aaaca38b5691794e0e052a42b9d95dd3c2) --- nova/tests/virt/vmwareapi/test_driver_api.py | 27 ++++++++++++++++++++++----- nova/virt/vmwareapi/vmops.py | 21 ++++++++++++++++----- 2 files changed, 38 insertions(+), 10 deletions(-) diff --git a/nova/tests/virt/vmwareapi/test_driver_api.py b/nova/tests/virt/vmwareapi/test_driver_api.py index fb60335..c1481aa 100644 --- a/nova/tests/virt/vmwareapi/test_driver_api.py +++ b/nova/tests/virt/vmwareapi/test_driver_api.py @@ -1273,14 +1273,31 @@ def test_rescue_with_config_drive(self): 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) diff --git a/nova/virt/vmwareapi/vmops.py b/nova/virt/vmwareapi/vmops.py index 0c28a29..30f8373 100644 --- a/nova/virt/vmwareapi/vmops.py +++ b/nova/virt/vmwareapi/vmops.py @@ -1159,12 +1159,26 @@ def unrescue(self, instance): "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 @@ def power_off(self, instance): # 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": -- 1.9.3