"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "ironic/drivers/modules/agent_base.py" between
ironic-16.0.2.tar.gz and ironic-16.0.3.tar.gz

About: OpenStack Ironic (Optional Service: Bare-Metal Provisioning) aims to provision bare metal machines instead of virtual machines, forked from the Nova baremetal driver.
The "Victoria" series (latest release).

agent_base.py  (ironic-16.0.2):agent_base.py  (ironic-16.0.3)
skipping to change at line 201 skipping to change at line 201
deploy_opts = deploy_utils.build_agent_options(task.node) deploy_opts = deploy_utils.build_agent_options(task.node)
task.driver.boot.prepare_ramdisk(task, deploy_opts) task.driver.boot.prepare_ramdisk(task, deploy_opts)
manager_utils.node_power_action(task, states.REBOOT) manager_utils.node_power_action(task, states.REBOOT)
except Exception as e: except Exception as e:
msg = (_('Reboot requested by %(type)s step %(step)s failed for ' msg = (_('Reboot requested by %(type)s step %(step)s failed for '
'node %(node)s: %(err)s') % 'node %(node)s: %(err)s') %
{'step': current_step, {'step': current_step,
'node': task.node.uuid, 'node': task.node.uuid,
'err': e, 'err': e,
'type': step_type}) 'type': step_type})
LOG.error(msg, exc_info=not isinstance(e, exception.IronicException)) traceback = not isinstance(e, exception.IronicException)
# do not set cleaning_reboot if we didn't reboot # do not set cleaning_reboot if we didn't reboot
if step_type == 'clean': if step_type == 'clean':
manager_utils.cleaning_error_handler(task, msg) manager_utils.cleaning_error_handler(task, msg,
traceback=traceback)
else: else:
manager_utils.deploying_error_handler(task, msg) manager_utils.deploying_error_handler(task, msg,
traceback=traceback)
return return
# Signify that we've rebooted # Signify that we've rebooted
driver_internal_info = task.node.driver_internal_info driver_internal_info = task.node.driver_internal_info
field = ('cleaning_reboot' if step_type == 'clean' field = ('cleaning_reboot' if step_type == 'clean'
else 'deployment_reboot') else 'deployment_reboot')
driver_internal_info[field] = True driver_internal_info[field] = True
if not driver_internal_info.get('agent_secret_token_pregenerated', False): if not driver_internal_info.get('agent_secret_token_pregenerated', False):
# Wipes out the existing recorded token because the machine will # Wipes out the existing recorded token because the machine will
# need to re-establish the token. # need to re-establish the token.
skipping to change at line 376 skipping to change at line 378
if not result.get('command_status'): if not result.get('command_status'):
_raise(step_type, _( _raise(step_type, _(
'Agent on node %(node)s returned bad command result: ' 'Agent on node %(node)s returned bad command result: '
'%(result)s') % {'node': task.node.uuid, 'result': result}) '%(result)s') % {'node': task.node.uuid, 'result': result})
return states.CLEANWAIT if step_type == 'clean' else states.DEPLOYWAIT return states.CLEANWAIT if step_type == 'clean' else states.DEPLOYWAIT
def execute_clean_step(task, step): def execute_clean_step(task, step):
# NOTE(dtantsur): left for compatibility with agent-based hardware types. # NOTE(dtantsur): left for compatibility with agent-based hardware types.
return execute_step(task, step, 'clean') return execute_step(task, step, 'clean')
def _step_failure_handler(task, msg, step_type): def _step_failure_handler(task, msg, step_type, traceback=False):
driver_utils.collect_ramdisk_logs( driver_utils.collect_ramdisk_logs(
task.node, label='cleaning' if step_type == 'clean' else None) task.node, label='cleaning' if step_type == 'clean' else None)
if step_type == 'clean': if step_type == 'clean':
manager_utils.cleaning_error_handler(task, msg) manager_utils.cleaning_error_handler(task, msg, traceback=traceback)
else: else:
manager_utils.deploying_error_handler(task, msg) manager_utils.deploying_error_handler(task, msg, traceback=traceback)
class HeartbeatMixin(object): class HeartbeatMixin(object):
"""Mixin class implementing heartbeat processing.""" """Mixin class implementing heartbeat processing."""
has_decomposed_deploy_steps = False has_decomposed_deploy_steps = False
"""Whether the driver supports decomposed deploy steps. """Whether the driver supports decomposed deploy steps.
Previously (since Rocky), drivers used a single 'deploy' deploy step on Previously (since Rocky), drivers used a single 'deploy' deploy step on
the deploy interface. Some additional steps were added for the 'direct' the deploy interface. Some additional steps were added for the 'direct'
and 'iscsi' deploy interfaces in the Ussuri cycle, which means that and 'iscsi' deploy interfaces in the Ussuri cycle, which means that
skipping to change at line 483 skipping to change at line 485
def heartbeat_allowed_states(self): def heartbeat_allowed_states(self):
"""Define node states where heartbeating is allowed""" """Define node states where heartbeating is allowed"""
if CONF.deploy.fast_track: if CONF.deploy.fast_track:
return FASTTRACK_HEARTBEAT_ALLOWED return FASTTRACK_HEARTBEAT_ALLOWED
return HEARTBEAT_ALLOWED return HEARTBEAT_ALLOWED
def _heartbeat_in_maintenance(self, task): def _heartbeat_in_maintenance(self, task):
node = task.node node = task.node
if (node.provision_state in (states.CLEANING, states.CLEANWAIT) if (node.provision_state in (states.CLEANING, states.CLEANWAIT)
and not CONF.conductor.allow_provisioning_in_maintenance): and not CONF.conductor.allow_provisioning_in_maintenance):
LOG.error('Aborting cleaning for node %s, as it is in maintenance ' log_msg = ('Aborting cleaning for node %s, as it is in '
'mode', node.uuid) 'maintenance mode' % node.uuid)
last_error = _('Cleaning aborted as node is in maintenance mode') last_error = _('Cleaning aborted as node is in maintenance mode')
manager_utils.cleaning_error_handler(task, last_error) manager_utils.cleaning_error_handler(task, log_msg,
errmsg=last_error)
elif (node.provision_state in (states.DEPLOYING, states.DEPLOYWAIT) elif (node.provision_state in (states.DEPLOYING, states.DEPLOYWAIT)
and not CONF.conductor.allow_provisioning_in_maintenance): and not CONF.conductor.allow_provisioning_in_maintenance):
LOG.error('Aborting deployment for node %s, as it is in ' LOG.error('Aborting deployment for node %s, as it is in '
'maintenance mode', node.uuid) 'maintenance mode', node.uuid)
last_error = _('Deploy aborted as node is in maintenance mode') last_error = _('Deploy aborted as node is in maintenance mode')
deploy_utils.set_failed_state(task, last_error, collect_logs=False) deploy_utils.set_failed_state(task, last_error, collect_logs=False)
elif (node.provision_state in (states.RESCUING, states.RESCUEWAIT) elif (node.provision_state in (states.RESCUING, states.RESCUEWAIT)
and not CONF.conductor.allow_provisioning_in_maintenance): and not CONF.conductor.allow_provisioning_in_maintenance):
LOG.error('Aborting rescuing for node %s, as it is in ' LOG.error('Aborting rescuing for node %s, as it is in '
'maintenance mode', node.uuid) 'maintenance mode', node.uuid)
skipping to change at line 577 skipping to change at line 580
else: else:
msg = _('Node failed to check cleaning progress') msg = _('Node failed to check cleaning progress')
# Check if the driver is polling for completion of a step, # Check if the driver is polling for completion of a step,
# via the 'cleaning_polling' flag. # via the 'cleaning_polling' flag.
polling = node.driver_internal_info.get( polling = node.driver_internal_info.get(
'cleaning_polling', False) 'cleaning_polling', False)
if not polling: if not polling:
self.continue_cleaning(task) self.continue_cleaning(task)
except Exception as e: except Exception as e:
last_error = _('%(msg)s. Error: %(exc)s') % {'msg': msg, 'exc': e} last_error = _('%(msg)s. Error: %(exc)s') % {'msg': msg, 'exc': e}
LOG.exception('Asynchronous exception for node %(node)s: %(err)s', log_msg = ('Asynchronous exception for node %(node)s: %(err)s' %
{'node': task.node.uuid, 'err': last_error}) {'node': task.node.uuid, 'err': last_error})
if node.provision_state in (states.CLEANING, states.CLEANWAIT): if node.provision_state in (states.CLEANING, states.CLEANWAIT):
manager_utils.cleaning_error_handler(task, last_error) manager_utils.cleaning_error_handler(task, log_msg,
errmsg=last_error)
def _heartbeat_rescue_wait(self, task): def _heartbeat_rescue_wait(self, task):
msg = _('Node failed to perform rescue operation') msg = _('Node failed to perform rescue operation')
try: try:
self._finalize_rescue(task) self._finalize_rescue(task)
except Exception as e: except Exception as e:
last_error = _('%(msg)s. Error: %(exc)s') % {'msg': msg, 'exc': e} last_error = _('%(msg)s. Error: %(exc)s') % {'msg': msg, 'exc': e}
LOG.exception('Asynchronous exception for node %(node)s: %(err)s', LOG.exception('Asynchronous exception for node %(node)s: %(err)s',
{'node': task.node.uuid, 'err': last_error}) {'node': task.node.uuid, 'err': last_error})
if task.node.provision_state in (states.RESCUING, if task.node.provision_state in (states.RESCUING,
skipping to change at line 996 skipping to change at line 1000
# for automated cleaning, it is (the default) AVAILABLE. # for automated cleaning, it is (the default) AVAILABLE.
manual_clean = node.target_provision_state == states.MANAGEABLE manual_clean = node.target_provision_state == states.MANAGEABLE
# Cache the new clean steps (and 'hardware_manager_version') # Cache the new clean steps (and 'hardware_manager_version')
try: try:
self.refresh_steps(task, step_type) self.refresh_steps(task, step_type)
except exception.NodeCleaningFailure as e: except exception.NodeCleaningFailure as e:
msg = (_('Could not continue cleaning on node ' msg = (_('Could not continue cleaning on node '
'%(node)s: %(err)s.') % '%(node)s: %(err)s.') %
{'node': node.uuid, 'err': e}) {'node': node.uuid, 'err': e})
LOG.exception(msg) return manager_utils.cleaning_error_handler(task, msg,
return manager_utils.cleaning_error_handler(task, msg) traceback=True)
except exception.InstanceDeployFailure as e: except exception.InstanceDeployFailure as e:
msg = (_('Could not continue deployment on node ' msg = (_('Could not continue deployment on node '
'%(node)s: %(err)s.') % '%(node)s: %(err)s.') %
{'node': node.uuid, 'err': e}) {'node': node.uuid, 'err': e})
LOG.exception(msg) return manager_utils.deploying_error_handler(task, msg,
return manager_utils.deploying_error_handler(task, msg) traceback=True)
if manual_clean: if manual_clean:
# Don't restart manual cleaning if agent reboots to a new # Don't restart manual cleaning if agent reboots to a new
# version. Both are operator actions, unlike automated # version. Both are operator actions, unlike automated
# cleaning. Manual clean steps are not necessarily idempotent # cleaning. Manual clean steps are not necessarily idempotent
# like automated clean steps and can be even longer running. # like automated clean steps and can be even longer running.
LOG.info('During manual cleaning, node %(node)s detected ' LOG.info('During manual cleaning, node %(node)s detected '
'a clean version mismatch. Re-executing and ' 'a clean version mismatch. Re-executing and '
'continuing from current step %(step)s.', 'continuing from current step %(step)s.',
{'node': node.uuid, 'step': node.clean_step}) {'node': node.uuid, 'step': node.clean_step})
skipping to change at line 1032 skipping to change at line 1036
'%(type)s version mismatch. Resetting %(type)s steps ' '%(type)s version mismatch. Resetting %(type)s steps '
'and rebooting the node.', 'and rebooting the node.',
{'type': step_type, 'node': node.uuid}) {'type': step_type, 'node': node.uuid})
try: try:
conductor_steps.set_node_cleaning_steps(task) conductor_steps.set_node_cleaning_steps(task)
except exception.NodeCleaningFailure as e: except exception.NodeCleaningFailure as e:
msg = (_('Could not restart automated cleaning on node ' msg = (_('Could not restart automated cleaning on node '
'%(node)s after step %(step)s: %(err)s.') % '%(node)s after step %(step)s: %(err)s.') %
{'node': node.uuid, 'err': e, {'node': node.uuid, 'err': e,
'step': node.clean_step}) 'step': node.clean_step})
LOG.exception(msg) return manager_utils.cleaning_error_handler(task, msg,
return manager_utils.cleaning_error_handler(task, msg) traceback=True)
except exception.InstanceDeployFailure as e: except exception.InstanceDeployFailure as e:
msg = (_('Could not restart deployment on node ' msg = (_('Could not restart deployment on node '
'%(node)s after step %(step)s: %(err)s.') % '%(node)s after step %(step)s: %(err)s.') %
{'node': node.uuid, 'err': e, {'node': node.uuid, 'err': e,
'step': node.deploy_step}) 'step': node.deploy_step})
LOG.exception(msg) return manager_utils.deploying_error_handler(task, msg,
return manager_utils.deploying_error_handler(task, msg) traceback=True)
manager_utils.notify_conductor_resume_operation(task, step_type) manager_utils.notify_conductor_resume_operation(task, step_type)
@METRICS.timer('AgentDeployMixin.process_next_step') @METRICS.timer('AgentDeployMixin.process_next_step')
def process_next_step(self, task, step_type, **kwargs): def process_next_step(self, task, step_type, **kwargs):
"""Start the next clean/deploy step if the previous one is complete. """Start the next clean/deploy step if the previous one is complete.
In order to avoid errors and make agent upgrades painless, the agent In order to avoid errors and make agent upgrades painless, the agent
compares the version of all hardware managers at the start of the compares the version of all hardware managers at the start of the
process (the agent's get_clean|deploy_steps() call) and before process (the agent's get_clean|deploy_steps() call) and before
skipping to change at line 1094 skipping to change at line 1098
# Agent command in progress # Agent command in progress
return return
if command.get('command_status') == 'FAILED': if command.get('command_status') == 'FAILED':
msg = (_('Agent returned error for %(type)s step %(step)s on node ' msg = (_('Agent returned error for %(type)s step %(step)s on node '
'%(node)s : %(err)s.') % '%(node)s : %(err)s.') %
{'node': node.uuid, {'node': node.uuid,
'err': agent_client.get_command_error(command), 'err': agent_client.get_command_error(command),
'step': current_step, 'step': current_step,
'type': step_type}) 'type': step_type})
LOG.error(msg)
return _step_failure_handler(task, msg, step_type) return _step_failure_handler(task, msg, step_type)
# NOTE(dtantsur): VERSION_MISMATCH is a new alias for # NOTE(dtantsur): VERSION_MISMATCH is a new alias for
# CLEAN_VERSION_MISMATCH, remove the old one after IPA removes it. # CLEAN_VERSION_MISMATCH, remove the old one after IPA removes it.
elif command.get('command_status') in ('CLEAN_VERSION_MISMATCH', elif command.get('command_status') in ('CLEAN_VERSION_MISMATCH',
'VERSION_MISMATCH'): 'VERSION_MISMATCH'):
self._process_version_mismatch(task, step_type) self._process_version_mismatch(task, step_type)
elif command.get('command_status') == 'SUCCEEDED': elif command.get('command_status') == 'SUCCEEDED':
step_hook = _get_post_step_hook(node, step_type) step_hook = _get_post_step_hook(node, step_type)
if step_hook is not None: if step_hook is not None:
LOG.debug('For node %(node)s, executing post %(type)s step ' LOG.debug('For node %(node)s, executing post %(type)s step '
skipping to change at line 1122 skipping to change at line 1125
except Exception as e: except Exception as e:
msg = (_('For node %(node)s, post %(type)s step hook ' msg = (_('For node %(node)s, post %(type)s step hook '
'%(method)s failed for %(type)s step %(step)s.' '%(method)s failed for %(type)s step %(step)s.'
'%(cls)s: %(error)s') % '%(cls)s: %(error)s') %
{'method': step_hook.__name__, {'method': step_hook.__name__,
'node': node.uuid, 'node': node.uuid,
'error': e, 'error': e,
'cls': e.__class__.__name__, 'cls': e.__class__.__name__,
'step': current_step, 'step': current_step,
'type': step_type}) 'type': step_type})
LOG.exception(msg) return _step_failure_handler(task, msg, step_type,
return _step_failure_handler(task, msg, step_type) traceback=True)
if current_step.get('reboot_requested'): if current_step.get('reboot_requested'):
_post_step_reboot(task, step_type) _post_step_reboot(task, step_type)
return return
LOG.info('Agent on node %(node)s returned %(type)s command ' LOG.info('Agent on node %(node)s returned %(type)s command '
'success, moving to next step', 'success, moving to next step',
{'node': node.uuid, 'type': step_type}) {'node': node.uuid, 'type': step_type})
manager_utils.notify_conductor_resume_operation(task, step_type) manager_utils.notify_conductor_resume_operation(task, step_type)
else: else:
msg = (_('Agent returned unknown status for %(type)s step %(step)s' msg = (_('Agent returned unknown status for %(type)s step %(step)s'
' on node %(node)s : %(err)s.') % ' on node %(node)s : %(err)s.') %
{'node': node.uuid, {'node': node.uuid,
'err': command.get('command_status'), 'err': command.get('command_status'),
'step': current_step, 'step': current_step,
'type': step_type}) 'type': step_type})
LOG.error(msg)
return _step_failure_handler(task, msg, step_type) return _step_failure_handler(task, msg, step_type)
@METRICS.timer('AgentDeployMixin.tear_down_agent') @METRICS.timer('AgentDeployMixin.tear_down_agent')
@base.deploy_step(priority=40) @base.deploy_step(priority=40)
@task_manager.require_exclusive_lock @task_manager.require_exclusive_lock
def tear_down_agent(self, task): def tear_down_agent(self, task):
"""A deploy step to tear down the agent. """A deploy step to tear down the agent.
:param task: a TaskManager object containing the node :param task: a TaskManager object containing the node
""" """
 End of changes. 17 change blocks. 
24 lines changed or deleted 26 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)