Provide PowerVMDriver.reboot

Implement nova_powervm.virt.powervm.driver.PowerVMDriver.reboot.

This implementation heeds the reboot_type (HARD or SOFT) parameter.

Change-Id: Ieaba2b676343a488ead9e06d3710c6c934b4e727
This commit is contained in:
Eric Fried 2015-04-20 10:33:42 -05:00
parent 2712f79a0c
commit 300c3d3a83
2 changed files with 76 additions and 3 deletions

View File

@ -26,6 +26,7 @@ from nova import test
from nova.tests.unit import fake_instance
from nova.virt import fake
import pypowervm.adapter as pvm_adp
import pypowervm.exceptions as pvm_exc
from pypowervm.tests.wrappers.util import pvmhttp
import pypowervm.wrappers.logical_partition as pvm_lpar
import pypowervm.wrappers.managed_system as pvm_ms
@ -603,7 +604,47 @@ class TestPowerVMDriver(test.TestCase):
self.assertTrue(
self.drv.disk_dvr.check_instance_shared_storage_cleanup.called)
def _fake_bdms(self):
@mock.patch('nova_powervm.virt.powervm.vm.get_instance_wrapper')
@mock.patch('pypowervm.tasks.power.power_on')
@mock.patch('pypowervm.tasks.power.power_off')
def test_reboot(self, mock_pwroff, mock_pwron, mock_instw):
entry = mock.Mock()
# State doesn't matter
entry.state = "whatever"
mock_instw.return_value = entry
inst = objects.Instance(**powervm.TEST_INSTANCE)
# Validate SOFT vs HARD and power_on called with each.
self.assertTrue(self.drv.reboot('context', inst, None, 'SOFT'))
mock_pwroff.assert_called_with(
self.drv.adapter, entry, self.drv.host_uuid, force_immediate=False)
mock_pwron.assert_called_with(mock.ANY, entry, self.drv.host_uuid)
self.assertTrue(self.drv.reboot('context', inst, None, 'HARD'))
mock_pwroff.assert_called_with(
self.drv.adapter, entry, self.drv.host_uuid, force_immediate=True)
self.assertEqual(2, mock_pwron.call_count)
mock_pwron.assert_called_with(mock.ANY, entry, self.drv.host_uuid)
# If power_on raises an exception, it percolates up.
mock_pwron.side_effect = pvm_exc.VMPowerOnFailure(lpar_nm='lpar',
reason='reason')
self.assertRaises(pvm_exc.VMPowerOnFailure, self.drv.reboot, 'context',
inst, None, 'SOFT')
# But power_off was called first.
mock_pwroff.assert_called_with(
self.drv.adapter, entry, self.drv.host_uuid, force_immediate=False)
# If power_off raises an exception, power_on is not called, and the
# exception percolates up.
pwron_count = mock_pwron.call_count
mock_pwroff.side_effect = pvm_exc.VMPowerOffFailure(lpar_nm='lpar',
reason='reason')
self.assertRaises(pvm_exc.VMPowerOffFailure, self.drv.reboot,
'context', inst, None, 'HARD')
self.assertEqual(pwron_count, mock_pwron.call_count)
@staticmethod
def _fake_bdms():
block_device_info = {
'block_device_mapping': [
{

View File

@ -34,6 +34,7 @@ import taskflow.task
from pypowervm import adapter as pvm_apt
from pypowervm.helpers import log_helper as log_hlp
from pypowervm.tasks import power as pvm_pwr
from pypowervm import util as pvm_util
from pypowervm.utils import retry as pvm_retry
from pypowervm.wrappers import managed_system as pvm_ms
@ -443,9 +444,7 @@ class PowerVMDriver(driver.ComputeDriver):
:param retry_interval: How often to signal guest while
waiting for it to shutdown
"""
self._log_operation('power_off', instance)
"""Power off the specified instance."""
vm.power_off(self.adapter, instance, self.host_uuid)
def power_on(self, context, instance, network_info,
@ -457,6 +456,39 @@ class PowerVMDriver(driver.ComputeDriver):
self._log_operation('power_on', instance)
vm.power_on(self.adapter, instance, self.host_uuid)
def reboot(self, context, instance, network_info, reboot_type,
block_device_info=None, bad_volumes_callback=None):
"""Reboot the specified instance.
After this is called successfully, the instance's state
goes back to power_state.RUNNING. The virtualization
platform should ensure that the reboot action has completed
successfully even in cases in which the underlying domain/vm
is paused or halted/stopped.
:param instance: nova.objects.instance.Instance
:param network_info:
:py:meth:`~nova.network.manager.NetworkManager.get_instance_nw_info`
:param reboot_type: Either a HARD or SOFT reboot
:param block_device_info: Info pertaining to attached volumes
:param bad_volumes_callback: Function to handle any bad volumes
encountered
"""
self._log_operation(reboot_type + ' reboot', instance)
force_immediate = reboot_type == 'HARD'
entry = vm.get_instance_wrapper(self.adapter, instance, self.host_uuid)
# Note: We're bypassing vm.power_off/_on because we don't want the
# state checks imposed thereby.
pvm_pwr.power_off(self.adapter, entry, self.host_uuid,
force_immediate=force_immediate)
# pypowervm does NOT throw an exception if "already down". Any other
# exception from pypowervm is a legitimate failure; let it raise up.
# If we get here, pypowervm thinks the instance is down.
pvm_pwr.power_on(self.adapter, entry, self.host_uuid)
# Again, pypowervm exceptions are sufficient to indicate real failure.
# Otherwise, pypowervm thinks the instance is up.
return True
def get_available_resource(self, nodename):
"""Retrieve resource information.