Merge "Ironic: Add soft reboot support to ironic driver"

This commit is contained in:
Jenkins
2017-01-24 11:59:37 +00:00
committed by Gerrit Code Review
4 changed files with 64 additions and 10 deletions

View File

@@ -1336,9 +1336,42 @@ class IronicDriverTestCase(test.NoDBTestCase):
mock_looping.return_value = fake_looping_call
instance = fake_instance.fake_instance_obj(self.ctx,
node=node.uuid)
self.driver.reboot(self.ctx, instance, None, None)
self.driver.reboot(self.ctx, instance, None, 'HARD')
mock_sp.assert_called_once_with(node.uuid, 'reboot')
@mock.patch.object(loopingcall, 'FixedIntervalLoopingCall')
@mock.patch.object(ironic_driver.IronicDriver,
'_validate_instance_and_node')
@mock.patch.object(FAKE_CLIENT.node, 'set_power_state')
def test_reboot_soft(self, mock_sp, fake_validate, mock_looping):
node = ironic_utils.get_test_node()
fake_validate.side_effect = [node, node]
fake_looping_call = FakeLoopingCall()
mock_looping.return_value = fake_looping_call
instance = fake_instance.fake_instance_obj(self.ctx,
node=node.uuid)
self.driver.reboot(self.ctx, instance, None, 'SOFT')
mock_sp.assert_called_once_with(node.uuid, 'reboot', soft=True)
@mock.patch.object(loopingcall, 'FixedIntervalLoopingCall')
@mock.patch.object(ironic_driver.IronicDriver,
'_validate_instance_and_node')
@mock.patch.object(FAKE_CLIENT.node, 'set_power_state')
def test_reboot_soft_not_supported(self, mock_sp, fake_validate,
mock_looping):
node = ironic_utils.get_test_node()
fake_validate.side_effect = [node, node]
mock_sp.side_effect = [ironic_exception.BadRequest(), None]
fake_looping_call = FakeLoopingCall()
mock_looping.return_value = fake_looping_call
instance = fake_instance.fake_instance_obj(self.ctx,
node=node.uuid)
self.driver.reboot(self.ctx, instance, None, 'SOFT')
mock_sp.assert_has_calls([mock.call(node.uuid, 'reboot', soft=True),
mock.call(node.uuid, 'reboot')])
@mock.patch.object(loopingcall, 'FixedIntervalLoopingCall')
@mock.patch.object(ironic_driver.IronicDriver,
'_validate_instance_and_node')

View File

@@ -147,7 +147,7 @@ class FakeNodeClient(object):
def list_ports(self, node_uuid, detail=False):
pass
def set_power_state(self, node_uuid, target):
def set_power_state(self, node_uuid, target, soft=False):
pass
def set_provision_state(self, node_uuid, target):

View File

@@ -993,8 +993,6 @@ class IronicDriver(virt_driver.ComputeDriver):
block_device_info=None, bad_volumes_callback=None):
"""Reboot the specified instance.
NOTE: Ironic does not support soft-off, so this method
always performs a hard-reboot.
NOTE: Unlike the libvirt driver, this method does not delete
and recreate the instance; it preserves local state.
@@ -1002,23 +1000,40 @@ class IronicDriver(virt_driver.ComputeDriver):
:param instance: The instance object.
:param network_info: Instance network information. Ignored by
this driver.
:param reboot_type: Either a HARD or SOFT reboot. Ignored by
this driver.
:param reboot_type: Either a HARD or SOFT reboot.
:param block_device_info: Info pertaining to attached volumes.
Ignored by this driver.
:param bad_volumes_callback: Function to handle any bad volumes
encountered. Ignored by this driver.
"""
LOG.debug('Reboot called for instance', instance=instance)
LOG.debug('Reboot(type %s) called for instance',
reboot_type, instance=instance)
node = self._validate_instance_and_node(instance)
self.ironicclient.call("node.set_power_state", node.uuid, 'reboot')
hard = True
if reboot_type == 'SOFT':
try:
self.ironicclient.call("node.set_power_state", node.uuid,
'reboot', soft=True)
hard = False
except ironic.exc.BadRequest as exc:
LOG.info(_LI('Soft reboot is not supported by ironic hardware '
'driver. Falling back to hard reboot: %s'),
exc,
instance=instance)
if hard:
self.ironicclient.call("node.set_power_state", node.uuid, 'reboot')
timer = loopingcall.FixedIntervalLoopingCall(
self._wait_for_power_state, instance, 'reboot')
timer.start(interval=CONF.ironic.api_retry_interval).wait()
LOG.info(_LI('Successfully rebooted Ironic node %s'),
node.uuid, instance=instance)
LOG.info(_LI('Successfully rebooted(type %(type)s) Ironic node '
'%(node)s'),
{'type': ('HARD' if hard else 'SOFT'),
'node': node.uuid},
instance=instance)
def power_off(self, instance, timeout=0, retry_interval=0):
"""Power off the specified instance.

View File

@@ -0,0 +1,6 @@
---
features:
- Adds soft reboot support to Ironic virt driver. If hardware driver in
Ironic doesn't support soft reboot, hard reboot is tried. This feature
requires the Ironic service to support API version 1.27 or later. It also
requires python-ironicclient >= 1.10.0.