[ansible] honor deploy_forces_oob_reboot
To use this driver property, tasks that soft poweroff the deploy ramdisk in-band are tagged with additional 'shutdown' tag and are executed separately. Change-Id: Ie7bae9dd9fa17a764599390362e1c7f6926c7746
This commit is contained in:
parent
6e8cd3163f
commit
e1ece310fa
@ -23,6 +23,7 @@ from ironic_lib import utils as irlib_utils
|
||||
from oslo_concurrency import processutils
|
||||
from oslo_config import cfg
|
||||
from oslo_log import log
|
||||
from oslo_utils import strutils
|
||||
from oslo_utils import units
|
||||
import retrying
|
||||
import six
|
||||
@ -386,7 +387,10 @@ class AnsibleDeploy(agent_base.HeartbeatMixin, base.DeployInterface):
|
||||
|
||||
def get_properties(self):
|
||||
"""Return the properties of the interface."""
|
||||
return COMMON_PROPERTIES
|
||||
props = COMMON_PROPERTIES.copy()
|
||||
# NOTE(pas-ha) this is to get the deploy_forces_oob_reboot property
|
||||
props.update(agent_base.VENDOR_PROPERTIES)
|
||||
return props
|
||||
|
||||
def validate(self, task):
|
||||
"""Validate the driver-specific Node deployment info."""
|
||||
@ -409,7 +413,9 @@ class AnsibleDeploy(agent_base.HeartbeatMixin, base.DeployInterface):
|
||||
|
||||
def _ansible_deploy(self, task, node_address):
|
||||
"""Internal function for deployment to a node."""
|
||||
notags = ['wait'] if CONF.ansible.use_ramdisk_callback else []
|
||||
notags = ['shutdown']
|
||||
if CONF.ansible.use_ramdisk_callback:
|
||||
notags.append('wait')
|
||||
node = task.node
|
||||
LOG.debug('IP of node %(node)s is %(ip)s',
|
||||
{'node': node.uuid, 'ip': node_address})
|
||||
@ -622,21 +628,33 @@ class AnsibleDeploy(agent_base.HeartbeatMixin, base.DeployInterface):
|
||||
return task.driver.power.get_power_state(task)
|
||||
|
||||
node = task.node
|
||||
oob_power_off = strutils.bool_from_string(
|
||||
node.driver_info.get('deploy_forces_oob_reboot', False))
|
||||
try:
|
||||
try:
|
||||
_wait_until_powered_off(task)
|
||||
except Exception as e:
|
||||
LOG.warning(_LW('Failed to soft power off node %(node_uuid)s '
|
||||
'in at least %(timeout)d seconds. '
|
||||
'Error: %(error)s'),
|
||||
{'node_uuid': task.node.uuid,
|
||||
'timeout': (wait * (attempts - 1)) / 1000,
|
||||
'error': e})
|
||||
# NOTE(pas-ha) flush is a part of deploy playbook
|
||||
# so if it finished successfully we can safely
|
||||
# power off the node out-of-band
|
||||
if not oob_power_off:
|
||||
try:
|
||||
node_address = _get_node_ip(task)
|
||||
playbook, user, key = _parse_ansible_driver_info(
|
||||
node)
|
||||
node_list = [(node.uuid, node_address, user, node.extra)]
|
||||
extra_vars = _prepare_extra_vars(node_list)
|
||||
_run_playbook(playbook, extra_vars, key,
|
||||
tags=['shutdown'])
|
||||
_wait_until_powered_off(task)
|
||||
except Exception as e:
|
||||
LOG.warning(
|
||||
_LW('Failed to soft power off node %(node_uuid)s '
|
||||
'in at least %(timeout)d seconds. '
|
||||
'Error: %(error)s'),
|
||||
{'node_uuid': node.uuid,
|
||||
'timeout': (wait * (attempts - 1)) / 1000,
|
||||
'error': e})
|
||||
# NOTE(pas-ha) flush is a part of deploy playbook
|
||||
# so if it finished successfully we can safely
|
||||
# power off the node out-of-band
|
||||
manager_utils.node_power_action(task, states.POWER_OFF)
|
||||
else:
|
||||
manager_utils.node_power_action(task, states.POWER_OFF)
|
||||
|
||||
task.driver.network.remove_provisioning_network(task)
|
||||
task.driver.network.configure_tenant_networks(task)
|
||||
manager_utils.node_power_action(task, states.POWER_ON)
|
||||
|
@ -9,5 +9,6 @@
|
||||
|
||||
- hosts: ironic
|
||||
roles:
|
||||
- deploy
|
||||
- shutdown
|
||||
- role: deploy
|
||||
- role: shutdown
|
||||
tags: shutdown
|
||||
|
@ -444,7 +444,8 @@ class TestAnsibleDeploy(db_base.DbTestCase):
|
||||
|
||||
def test_get_properties(self):
|
||||
self.assertEqual(
|
||||
set(ansible_deploy.COMMON_PROPERTIES),
|
||||
set(list(ansible_deploy.COMMON_PROPERTIES) +
|
||||
['deploy_forces_oob_reboot']),
|
||||
set(self.driver.get_properties()))
|
||||
|
||||
@mock.patch.object(deploy_utils, 'check_for_missing_params',
|
||||
@ -792,7 +793,7 @@ class TestAnsibleDeploy(db_base.DbTestCase):
|
||||
(self.node['uuid'],
|
||||
DRIVER_INTERNAL_INFO['ansible_cleaning_ip'],
|
||||
'test_u')]}, 'test_k',
|
||||
notags=['wait'])
|
||||
notags=['shutdown', 'wait'])
|
||||
|
||||
@mock.patch.object(ansible_deploy, '_run_playbook', autospec=True)
|
||||
@mock.patch.object(ansible_deploy, '_prepare_extra_vars', autospec=True)
|
||||
@ -834,14 +835,43 @@ class TestAnsibleDeploy(db_base.DbTestCase):
|
||||
(self.node['uuid'],
|
||||
DRIVER_INTERNAL_INFO['ansible_cleaning_ip'],
|
||||
'test_u')]}, 'test_k',
|
||||
notags=['wait', 'parted'])
|
||||
notags=['shutdown', 'wait', 'parted'])
|
||||
|
||||
@mock.patch.object(fake.FakePower, 'get_power_state',
|
||||
return_value=states.POWER_OFF)
|
||||
@mock.patch.object(utils, 'node_power_action', autospec=True)
|
||||
def test_reboot_and_finish_deploy_force_reboot(self, power_action_mock,
|
||||
get_pow_state_mock):
|
||||
d_info = self.node.driver_info
|
||||
d_info['deploy_forces_oob_reboot'] = True
|
||||
self.node.driver_info = d_info
|
||||
self.node.save()
|
||||
self.config(group='ansible',
|
||||
post_deploy_get_power_state_retry_interval=0)
|
||||
self.node.provision_state = states.DEPLOYING
|
||||
self.node.save()
|
||||
|
||||
with task_manager.acquire(self.context, self.node.uuid) as task:
|
||||
with mock.patch.object(task.driver, 'network') as net_mock:
|
||||
self.driver.reboot_and_finish_deploy(task)
|
||||
net_mock.remove_provisioning_network.assert_called_once_with(
|
||||
task)
|
||||
net_mock.configure_tenant_networks.assert_called_once_with(
|
||||
task)
|
||||
expected_power_calls = [((task, states.POWER_OFF),),
|
||||
((task, states.POWER_ON),)]
|
||||
self.assertEqual(expected_power_calls,
|
||||
power_action_mock.call_args_list)
|
||||
get_pow_state_mock.assert_not_called()
|
||||
|
||||
@mock.patch.object(ansible_deploy, '_run_playbook', autospec=True)
|
||||
@mock.patch.object(utils, 'node_power_action', autospec=True)
|
||||
@mock.patch.object(fake.FakePower, 'get_power_state',
|
||||
return_value=states.POWER_ON)
|
||||
def test_reboot_and_finish_deploy_soft_poweroff_retry(self,
|
||||
get_pow_state_mock,
|
||||
power_action_mock):
|
||||
power_action_mock,
|
||||
ansible_mock):
|
||||
self.config(group='ansible',
|
||||
post_deploy_get_power_state_retry_interval=0)
|
||||
self.config(group='ansible',
|
||||
@ -868,6 +898,8 @@ class TestAnsibleDeploy(db_base.DbTestCase):
|
||||
((task, states.POWER_ON),)]
|
||||
self.assertEqual(expected_power_calls,
|
||||
power_action_mock.call_args_list)
|
||||
ansible_mock.assert_called_once_with(mock.ANY, mock.ANY, mock.ANY,
|
||||
tags=['shutdown'])
|
||||
|
||||
@mock.patch.object(ansible_deploy, '_get_node_ip_heartbeat', autospec=True,
|
||||
return_value='1.2.3.4')
|
||||
|
@ -0,0 +1,5 @@
|
||||
---
|
||||
features:
|
||||
- |
|
||||
ansible-deploy driver now honors ``deploy-forces-oob-reboot`` driver
|
||||
property
|
Loading…
Reference in New Issue
Block a user