From 115a5957560bfc8a0bebe5ca4d723b71f2450821 Mon Sep 17 00:00:00 2001 From: Yaguang Tang Date: Thu, 23 May 2013 12:29:41 +0800 Subject: Add resume state on host boot function to vmware Hyper. Fix bug #1183426 Change-Id: Ia4a0cce285aac01c59286f4899cbac0a021039c4 --- nova/tests/virt/vmwareapi/test_vmwareapi.py | 34 +++++++++++++++++++++++++++++ nova/virt/vmwareapi/driver.py | 22 +++++++++++++++++++ nova/virt/vmwareapi/vm_util.py | 7 ++++++ 3 files changed, 63 insertions(+) diff --git a/nova/tests/virt/vmwareapi/test_vmwareapi.py b/nova/tests/virt/vmwareapi/test_vmwareapi.py index afda26b0d..7b1829b84 100644 --- a/nova/tests/virt/vmwareapi/test_vmwareapi.py +++ b/nova/tests/virt/vmwareapi/test_vmwareapi.py @@ -365,6 +365,40 @@ class VMwareAPIVMTestCase(test.TestCase): self.assertRaises(exception.InstancePowerOffFailure, self.conn.power_off, self.instance) + def test_resume_state_on_host_boot(self): + self._create_vm() + self.mox.StubOutWithMock(vm_util, 'get_vm_state_from_name') + self.mox.StubOutWithMock(self.conn, "reboot") + vm_util.get_vm_state_from_name(mox.IgnoreArg(), + self.instance['uuid']).AndReturn("poweredOff") + self.conn.reboot(self.context, self.instance, 'network_info', + 'hard', None) + self.mox.ReplayAll() + self.conn.resume_state_on_host_boot(self.context, self.instance, + 'network_info') + + def test_resume_state_on_host_boot_no_reboot_1(self): + """Don't call reboot on instance which is poweredon.""" + self._create_vm() + self.mox.StubOutWithMock(vm_util, 'get_vm_state_from_name') + self.mox.StubOutWithMock(self.conn, 'reboot') + vm_util.get_vm_state_from_name(mox.IgnoreArg(), + self.instance['uuid']).AndReturn("poweredOn") + self.mox.ReplayAll() + self.conn.resume_state_on_host_boot(self.context, self.instance, + 'network_info') + + def test_resume_state_on_host_boot_no_reboot_2(self): + """Don't call reboot on instance which is suspended.""" + self._create_vm() + self.mox.StubOutWithMock(vm_util, 'get_vm_state_from_name') + self.mox.StubOutWithMock(self.conn, 'reboot') + vm_util.get_vm_state_from_name(mox.IgnoreArg(), + self.instance['uuid']).AndReturn("suspended") + self.mox.ReplayAll() + self.conn.resume_state_on_host_boot(self.context, self.instance, + 'network_info') + def test_get_info(self): self._create_vm() info = self.conn.get_info({'uuid': 'fake-uuid'}) diff --git a/nova/virt/vmwareapi/driver.py b/nova/virt/vmwareapi/driver.py index 8389b2c3d..ef06d447a 100755 --- a/nova/virt/vmwareapi/driver.py +++ b/nova/virt/vmwareapi/driver.py @@ -229,6 +229,28 @@ class VMwareESXDriver(driver.ComputeDriver): """Power on the specified instance.""" self._vmops._power_on(instance) + def resume_state_on_host_boot(self, context, instance, network_info, + block_device_info=None): + """resume guest state when a host is booted.""" + # Check if the instance is running already and avoid doing + # anything if it is. + instances = self.list_instances() + if instance['uuid'] not in instances: + LOG.warn(_('Instance cannot be found in host, or in an unknown' + 'state.'), instance=instance) + else: + state = vm_util.get_vm_state_from_name(self._session, + instance['uuid']) + ignored_states = ['poweredon', 'suspended'] + + if state.lower() in ignored_states: + return + # Instance is not up and could be in an unknown state. + # Be as absolute as possible about getting it back into + # a known and running state. + self.reboot(context, instance, network_info, 'hard', + block_device_info) + def poll_rebooting_instances(self, timeout, instances): """Poll for rebooting instances.""" self._vmops.poll_rebooting_instances(timeout, instances) diff --git a/nova/virt/vmwareapi/vm_util.py b/nova/virt/vmwareapi/vm_util.py index d8e063cad..94da5c677 100644 --- a/nova/virt/vmwareapi/vm_util.py +++ b/nova/virt/vmwareapi/vm_util.py @@ -632,6 +632,13 @@ def get_host_name_from_host_ref(host_ref): return p.val +def get_vm_state_from_name(session, vm_name): + vm_ref = get_vm_ref_from_name(session, vm_name) + vm_state = session._call_method(vim_util, "get_dynamic_property", + vm_ref, "VirtualMachine", "runtime.powerState") + return vm_state + + def get_cluster_ref_from_name(session, cluster_name): """Get reference to the cluster with the name specified.""" cls = session._call_method(vim_util, "get_objects", -- cgit