summaryrefslogtreecommitdiff
path: root/ironic
diff options
context:
space:
mode:
authorDmitry Tantsur <dtantsur@protonmail.com>2020-09-25 14:21:29 +0200
committerDmitry Tantsur <dtantsur@protonmail.com>2020-10-06 17:27:24 +0200
commit1dfb61dc4fe1e66743b83a08af96ef6ab1e6bf26 (patch)
treedfe2f9d1d256a5ccc056c8604e6b09a5117fbe70 /ironic
parentc9c605d8b83270edbdb56c6e77d2a2ec339bba3e (diff)
downloadironic-1dfb61dc4fe1e66743b83a08af96ef6ab1e6bf26.tar.gz
Refactoring: split away continue_node_deploy/clean
To be able to get rid of using RPC for continuing async steps we need this code to be callable. Change-Id: I87ec9c39fa00226b196605af97d528b268f304c7
Diffstat (limited to 'ironic')
-rw-r--r--ironic/conductor/cleaning.py45
-rw-r--r--ironic/conductor/deployments.py36
-rw-r--r--ironic/conductor/manager.py81
-rw-r--r--ironic/conductor/utils.py30
-rw-r--r--ironic/tests/unit/conductor/test_cleaning.py29
-rw-r--r--ironic/tests/unit/conductor/test_deployments.py77
-rw-r--r--ironic/tests/unit/conductor/test_manager.py189
7 files changed, 224 insertions, 263 deletions
diff --git a/ironic/conductor/cleaning.py b/ironic/conductor/cleaning.py
index 399cdc1ee..c279e2fcd 100644
--- a/ironic/conductor/cleaning.py
+++ b/ironic/conductor/cleaning.py
@@ -266,3 +266,48 @@ def do_node_clean_abort(task, step_name=None):
utils.wipe_cleaning_internal_info(task)
node.save()
LOG.info(info_message)
+
+
+@utils.fail_on_error(utils.cleaning_error_handler,
+ _("Unexpected error when processing next clean step"))
+@task_manager.require_exclusive_lock
+def continue_node_clean(task):
+ """Continue cleaning after finishing an async clean step.
+
+ This function calculates which step has to run next and passes control
+ into do_next_clean_step.
+
+ :param task: a TaskManager instance with an exclusive lock
+ """
+ node = task.node
+
+ next_step_index = utils.update_next_step_index(task, 'clean')
+
+ # If this isn't the final clean step in the cleaning operation
+ # and it is flagged to abort after the clean step that just
+ # finished, we abort the cleaning operation.
+ if node.clean_step.get('abort_after'):
+ step_name = node.clean_step['step']
+ if next_step_index is not None:
+ LOG.debug('The cleaning operation for node %(node)s was '
+ 'marked to be aborted after step "%(step)s '
+ 'completed. Aborting now that it has completed.',
+ {'node': task.node.uuid, 'step': step_name})
+
+ if node.target_provision_state == states.MANAGEABLE:
+ target_state = states.MANAGEABLE
+ else:
+ target_state = None
+
+ task.process_event('fail', target_state=target_state)
+ do_node_clean_abort(task, step_name)
+ return
+
+ LOG.debug('The cleaning operation for node %(node)s was '
+ 'marked to be aborted after step "%(step)s" '
+ 'completed. However, since there are no more '
+ 'clean steps after this, the abort is not going '
+ 'to be done.', {'node': node.uuid,
+ 'step': step_name})
+
+ do_next_clean_step(task, next_step_index)
diff --git a/ironic/conductor/deployments.py b/ironic/conductor/deployments.py
index 9fdfe84cc..8758ae08d 100644
--- a/ironic/conductor/deployments.py
+++ b/ironic/conductor/deployments.py
@@ -323,6 +323,42 @@ def do_next_deploy_step(task, step_index):
{'node': node.uuid, 'instance': node.instance_uuid})
+@utils.fail_on_error(utils.deploying_error_handler,
+ _("Unexpected error when processing next deploy step"))
+@task_manager.require_exclusive_lock
+def continue_node_deploy(task):
+ """Continue deployment after finishing an async deploy step.
+
+ This function calculates which step has to run next and passes control
+ into do_next_deploy_step. On the first run, deploy steps and templates are
+ also validated.
+
+ :param task: a TaskManager instance with an exclusive lock
+ """
+ node = task.node
+
+ # Agent is now running, we're ready to validate the remaining steps
+ if not node.driver_internal_info.get('steps_validated'):
+ try:
+ conductor_steps.validate_deploy_templates(task)
+ conductor_steps.set_node_deployment_steps(
+ task, reset_current=False)
+ except exception.IronicException as exc:
+ msg = _('Failed to validate the final deploy steps list '
+ 'for node %(node)s: %(exc)s') % {'node': node.uuid,
+ 'exc': exc}
+ return utils.deploying_error_handler(task, msg)
+
+ info = node.driver_internal_info
+ info['steps_validated'] = True
+ node.driver_internal_info = info
+ node.save()
+
+ next_step_index = utils.update_next_step_index(task, 'deploy')
+
+ do_next_deploy_step(task, next_step_index)
+
+
def _get_configdrive_obj_name(node):
"""Generate the object name for the config drive."""
return 'configdrive-%s' % node.uuid
diff --git a/ironic/conductor/manager.py b/ironic/conductor/manager.py
index 406f6945f..7fcccec04 100644
--- a/ironic/conductor/manager.py
+++ b/ironic/conductor/manager.py
@@ -879,38 +879,6 @@ class ConductorManager(base_manager.BaseConductorManager):
'state': node.provision_state,
'deploy_state': ', '.join(expected_states)})
- save_required = False
- info = node.driver_internal_info
-
- # Agent is now running, we're ready to validate the remaining steps
- if not info.get('steps_validated'):
- try:
- conductor_steps.validate_deploy_templates(task)
- conductor_steps.set_node_deployment_steps(
- task, reset_current=False)
- except exception.IronicException as exc:
- msg = _('Failed to validate the final deploy steps list '
- 'for node %(node)s: %(exc)s') % {'node': node.uuid,
- 'exc': exc}
- return utils.deploying_error_handler(task, msg)
- info['steps_validated'] = True
- save_required = True
-
- try:
- skip_current_step = info.pop('skip_current_deploy_step')
- except KeyError:
- skip_current_step = True
- else:
- save_required = True
- if info.pop('deployment_polling', None) is not None:
- save_required = True
- if save_required:
- node.driver_internal_info = info
- node.save()
-
- next_step_index = utils.get_node_next_deploy_steps(
- task, skip_current_step=skip_current_step)
-
# TODO(rloo): When deprecation period is over and node is in
# states.DEPLOYWAIT only, delete the check and always 'resume'.
if node.provision_state == states.DEPLOYING:
@@ -927,8 +895,7 @@ class ConductorManager(base_manager.BaseConductorManager):
task.node)
task.spawn_after(
self._spawn_worker,
- deployments.do_next_deploy_step,
- task, next_step_index)
+ deployments.continue_node_deploy, task)
@METRICS.timer('ConductorManager.do_node_tear_down')
@messaging.expected_exceptions(exception.NoFreeConductorWorker,
@@ -1167,57 +1134,13 @@ class ConductorManager(base_manager.BaseConductorManager):
'state': node.provision_state,
'clean_state': states.CLEANWAIT})
- save_required = False
- info = node.driver_internal_info
- try:
- skip_current_step = info.pop('skip_current_clean_step')
- except KeyError:
- skip_current_step = True
- else:
- save_required = True
- if info.pop('cleaning_polling', None) is not None:
- save_required = True
- if save_required:
- node.driver_internal_info = info
- node.save()
-
- next_step_index = utils.get_node_next_clean_steps(
- task, skip_current_step=skip_current_step)
-
- # If this isn't the final clean step in the cleaning operation
- # and it is flagged to abort after the clean step that just
- # finished, we abort the cleaning operation.
- if node.clean_step.get('abort_after'):
- step_name = node.clean_step['step']
- if next_step_index is not None:
- LOG.debug('The cleaning operation for node %(node)s was '
- 'marked to be aborted after step "%(step)s '
- 'completed. Aborting now that it has completed.',
- {'node': task.node.uuid, 'step': step_name})
- task.process_event(
- 'abort',
- callback=self._spawn_worker,
- call_args=(cleaning.do_node_clean_abort,
- task, step_name),
- err_handler=utils.provisioning_error_handler,
- target_state=target_state)
- return
-
- LOG.debug('The cleaning operation for node %(node)s was '
- 'marked to be aborted after step "%(step)s" '
- 'completed. However, since there are no more '
- 'clean steps after this, the abort is not going '
- 'to be done.', {'node': node.uuid,
- 'step': step_name})
-
task.process_event('resume', target_state=target_state)
task.set_spawn_error_hook(utils.spawn_cleaning_error_handler,
task.node)
task.spawn_after(
self._spawn_worker,
- cleaning.do_next_clean_step,
- task, next_step_index)
+ cleaning.continue_node_clean, task)
@task_manager.require_exclusive_lock
def _do_node_verify(self, task):
diff --git a/ironic/conductor/utils.py b/ironic/conductor/utils.py
index dc52d33b0..b1a007223 100644
--- a/ironic/conductor/utils.py
+++ b/ironic/conductor/utils.py
@@ -1121,6 +1121,36 @@ def get_node_next_deploy_steps(task, skip_current_step=True):
skip_current_step=skip_current_step)
+def update_next_step_index(task, step_type):
+ """Calculate the next step index and update the node.
+
+ :param task: A TaskManager object
+ :param step_type: The type of steps to process: 'clean' or 'deploy'.
+ :returns: Index of the next step.
+ """
+ info = task.node.driver_internal_info
+ save_required = False
+
+ try:
+ skip_current_step = info.pop('skip_current_%s_step' % step_type)
+ except KeyError:
+ skip_current_step = True
+ else:
+ save_required = True
+
+ field = ('cleaning_polling' if step_type == 'clean'
+ else 'deployment_polling')
+ if info.pop(field, None) is not None:
+ save_required = True
+
+ if save_required:
+ task.node.driver_internal_info = info
+ task.node.save()
+
+ return _get_node_next_steps(task, step_type,
+ skip_current_step=skip_current_step)
+
+
def add_secret_token(node, pregenerated=False):
"""Adds a secret token to driver_internal_info for IPA verification.
diff --git a/ironic/tests/unit/conductor/test_cleaning.py b/ironic/tests/unit/conductor/test_cleaning.py
index 6ed4bd270..0bcb1c77f 100644
--- a/ironic/tests/unit/conductor/test_cleaning.py
+++ b/ironic/tests/unit/conductor/test_cleaning.py
@@ -995,6 +995,35 @@ class DoNodeCleanTestCase(db_base.DbTestCase):
def test__do_next_clean_step_manual_bad_step_return_value(self):
self._do_next_clean_step_bad_step_return_value(manual=True)
+ @mock.patch.object(cleaning, 'do_next_clean_step', autospec=True)
+ def _continue_node_clean(self, mock_next_step, skip=True):
+ # test that skipping current step mechanism works
+ driver_info = {'clean_steps': self.clean_steps,
+ 'clean_step_index': 0,
+ 'cleaning_polling': 'value'}
+ if not skip:
+ driver_info['skip_current_clean_step'] = skip
+ node = obj_utils.create_test_node(
+ self.context, driver='fake-hardware',
+ provision_state=states.CLEANING,
+ target_provision_state=states.MANAGEABLE,
+ driver_internal_info=driver_info,
+ clean_step=self.clean_steps[0])
+ with task_manager.acquire(self.context, node.uuid) as task:
+ cleaning.continue_node_clean(task)
+ expected_step_index = 1 if skip else 0
+ self.assertNotIn(
+ 'skip_current_clean_step', task.node.driver_internal_info)
+ self.assertNotIn(
+ 'cleaning_polling', task.node.driver_internal_info)
+ mock_next_step.assert_called_once_with(task, expected_step_index)
+
+ def test_continue_node_clean(self):
+ self._continue_node_clean(skip=True)
+
+ def test_continue_node_clean_no_skip_step(self):
+ self._continue_node_clean(skip=False)
+
class DoNodeCleanAbortTestCase(db_base.DbTestCase):
@mock.patch.object(fake.FakeDeploy, 'tear_down_cleaning', autospec=True)
diff --git a/ironic/tests/unit/conductor/test_deployments.py b/ironic/tests/unit/conductor/test_deployments.py
index bafe3363f..6cff78acb 100644
--- a/ironic/tests/unit/conductor/test_deployments.py
+++ b/ironic/tests/unit/conductor/test_deployments.py
@@ -428,6 +428,8 @@ class DoNextDeployStepTestCase(mgr_utils.ServiceSetUpMixin,
self.deploy_end = {
'step': 'deploy_end', 'priority': 20, 'interface': 'deploy'}
self.deploy_steps = [self.deploy_start, self.deploy_end]
+ self.in_band_step = {
+ 'step': 'deploy_middle', 'priority': 30, 'interface': 'deploy'}
@mock.patch.object(deployments, 'LOG', autospec=True)
def test__do_next_deploy_step_none(self, mock_log):
@@ -811,6 +813,81 @@ class DoNextDeployStepTestCase(mgr_utils.ServiceSetUpMixin,
mock_execute.assert_called_once_with(
mock.ANY, mock.ANY, self.deploy_steps[0])
+ @mock.patch.object(deployments, 'do_next_deploy_step', autospec=True)
+ def _continue_node_deploy(self, mock_next_step, skip=True):
+ driver_info = {'deploy_steps': self.deploy_steps,
+ 'deploy_step_index': 0,
+ 'deployment_polling': 'value'}
+ if not skip:
+ driver_info['skip_current_deploy_step'] = skip
+ node = obj_utils.create_test_node(
+ self.context, driver='fake-hardware',
+ provision_state=states.DEPLOYING,
+ driver_internal_info=driver_info,
+ deploy_step=self.deploy_steps[0])
+ with task_manager.acquire(self.context, node.uuid) as task:
+ deployments.continue_node_deploy(task)
+ expected_step_index = None if skip else 0
+ self.assertNotIn(
+ 'skip_current_deploy_step', task.node.driver_internal_info)
+ self.assertNotIn(
+ 'deployment_polling', task.node.driver_internal_info)
+ mock_next_step.assert_called_once_with(task, expected_step_index)
+
+ def test_continue_node_deploy(self):
+ self._continue_node_deploy(skip=True)
+
+ def test_continue_node_deploy_no_skip_step(self):
+ self._continue_node_deploy(skip=False)
+
+ @mock.patch.object(deployments, 'do_next_deploy_step', autospec=True)
+ @mock.patch('ironic.drivers.modules.fake.FakeDeploy.get_deploy_steps',
+ autospec=True)
+ def test_continue_node_deploy_first_agent_boot(self, mock_get_steps,
+ mock_next_step):
+ new_steps = [self.deploy_start, self.in_band_step, self.deploy_end]
+ mock_get_steps.return_value = new_steps
+ driver_info = {'deploy_steps': self.deploy_steps,
+ 'deploy_step_index': 0}
+ node = obj_utils.create_test_node(self.context, driver='fake-hardware',
+ provision_state=states.DEPLOYING,
+ target_provision_state=states.ACTIVE,
+ last_error=None,
+ driver_internal_info=driver_info,
+ deploy_step=self.deploy_steps[0])
+ with task_manager.acquire(self.context, node.uuid) as task:
+ deployments.continue_node_deploy(task)
+ self.assertEqual(states.DEPLOYING, task.node.provision_state)
+ self.assertTrue(task.node.driver_internal_info['steps_validated'])
+ self.assertEqual(new_steps,
+ task.node.driver_internal_info['deploy_steps'])
+ mock_next_step.assert_called_once_with(task, 1)
+
+ @mock.patch.object(deployments, 'do_next_deploy_step', autospec=True)
+ @mock.patch.object(conductor_steps, 'validate_deploy_templates',
+ autospec=True)
+ def test_continue_node_steps_validation(self, mock_validate,
+ mock_next_step):
+ tgt_prv_state = states.ACTIVE
+ mock_validate.side_effect = exception.InvalidParameterValue('boom')
+ driver_info = {'deploy_steps': self.deploy_steps,
+ 'deploy_step_index': 0,
+ 'steps_validated': False}
+ node = obj_utils.create_test_node(self.context, driver='fake-hardware',
+ provision_state=states.DEPLOYING,
+ target_provision_state=tgt_prv_state,
+ last_error=None,
+ driver_internal_info=driver_info,
+ deploy_step=self.deploy_steps[0])
+ with task_manager.acquire(self.context, node.uuid) as task:
+ deployments.continue_node_deploy(task)
+ self.assertEqual(states.DEPLOYFAIL, task.node.provision_state)
+ self.assertIn('Failed to validate the final deploy steps',
+ task.node.last_error)
+ self.assertIn('boom', task.node.last_error)
+ self.assertEqual(tgt_prv_state, node.target_provision_state)
+ self.assertFalse(mock_next_step.called)
+
@mock.patch.object(swift, 'SwiftAPI', autospec=True)
class StoreConfigDriveTestCase(db_base.DbTestCase):
diff --git a/ironic/tests/unit/conductor/test_manager.py b/ironic/tests/unit/conductor/test_manager.py
index 485e73665..648e86c98 100644
--- a/ironic/tests/unit/conductor/test_manager.py
+++ b/ironic/tests/unit/conductor/test_manager.py
@@ -1718,8 +1718,6 @@ class ContinueNodeDeployTestCase(mgr_utils.ServiceSetUpMixin,
'step': 'deploy_start', 'priority': 50, 'interface': 'deploy'}
self.deploy_end = {
'step': 'deploy_end', 'priority': 20, 'interface': 'deploy'}
- self.in_band_step = {
- 'step': 'deploy_middle', 'priority': 30, 'interface': 'deploy'}
self.deploy_steps = [self.deploy_start, self.deploy_end]
@mock.patch('ironic.conductor.manager.ConductorManager._spawn_worker',
@@ -1771,14 +1769,10 @@ class ContinueNodeDeployTestCase(mgr_utils.ServiceSetUpMixin,
# test a node can continue deploying via RPC
prv_state = states.DEPLOYWAIT
tgt_prv_state = states.ACTIVE
- driver_info = {'deploy_steps': self.deploy_steps,
- 'deploy_step_index': 0,
- 'steps_validated': True}
node = obj_utils.create_test_node(self.context, driver='fake-hardware',
provision_state=prv_state,
target_provision_state=tgt_prv_state,
last_error=None,
- driver_internal_info=driver_info,
deploy_step=self.deploy_steps[0])
self._start_service()
self.service.continue_node_deploy(self.context, node.uuid)
@@ -1787,38 +1781,8 @@ class ContinueNodeDeployTestCase(mgr_utils.ServiceSetUpMixin,
self.assertEqual(states.DEPLOYING, node.provision_state)
self.assertEqual(tgt_prv_state, node.target_provision_state)
mock_spawn.assert_called_with(mock.ANY,
- deployments.do_next_deploy_step,
- mock.ANY, 1)
-
- @mock.patch('ironic.drivers.modules.fake.FakeDeploy.get_deploy_steps',
- autospec=True)
- @mock.patch('ironic.conductor.manager.ConductorManager._spawn_worker',
- autospec=True)
- def test_continue_node_deploy_first_agent_boot(self, mock_spawn,
- mock_get_steps):
- new_steps = [self.deploy_start, self.in_band_step, self.deploy_end]
- mock_get_steps.return_value = new_steps
- prv_state = states.DEPLOYWAIT
- tgt_prv_state = states.ACTIVE
- driver_info = {'deploy_steps': self.deploy_steps,
- 'deploy_step_index': 0}
- node = obj_utils.create_test_node(self.context, driver='fake-hardware',
- provision_state=prv_state,
- target_provision_state=tgt_prv_state,
- last_error=None,
- driver_internal_info=driver_info,
- deploy_step=self.deploy_steps[0])
- self._start_service()
- self.service.continue_node_deploy(self.context, node.uuid)
- self._stop_service()
- node.refresh()
- self.assertEqual(states.DEPLOYING, node.provision_state)
- self.assertEqual(tgt_prv_state, node.target_provision_state)
- self.assertTrue(node.driver_internal_info['steps_validated'])
- self.assertEqual(new_steps, node.driver_internal_info['deploy_steps'])
- mock_spawn.assert_called_with(mock.ANY,
- deployments.do_next_deploy_step,
- mock.ANY, 1)
+ deployments.continue_node_deploy,
+ mock.ANY)
@mock.patch.object(task_manager.TaskManager, 'process_event',
autospec=True)
@@ -1847,95 +1811,10 @@ class ContinueNodeDeployTestCase(mgr_utils.ServiceSetUpMixin,
self.assertEqual(states.DEPLOYING, node.provision_state)
self.assertEqual(tgt_prv_state, node.target_provision_state)
mock_spawn.assert_called_with(mock.ANY,
- deployments.do_next_deploy_step,
- mock.ANY, 1)
+ deployments.continue_node_deploy,
+ mock.ANY)
self.assertFalse(mock_event.called)
- @mock.patch('ironic.conductor.manager.ConductorManager._spawn_worker',
- autospec=True)
- def _continue_node_deploy_skip_step(self, mock_spawn, skip=True):
- # test that skipping current step mechanism works
- driver_info = {'deploy_steps': self.deploy_steps,
- 'deploy_step_index': 0,
- 'steps_validated': True}
- if not skip:
- driver_info['skip_current_deploy_step'] = skip
- node = obj_utils.create_test_node(
- self.context, driver='fake-hardware',
- provision_state=states.DEPLOYWAIT,
- target_provision_state=states.MANAGEABLE,
- driver_internal_info=driver_info, deploy_step=self.deploy_steps[0])
- self._start_service()
- self.service.continue_node_deploy(self.context, node.uuid)
- self._stop_service()
- node.refresh()
- if skip:
- expected_step_index = 1
- else:
- self.assertNotIn(
- 'skip_current_deploy_step', node.driver_internal_info)
- expected_step_index = 0
- mock_spawn.assert_called_with(mock.ANY,
- deployments.do_next_deploy_step,
- mock.ANY, expected_step_index)
-
- def test_continue_node_deploy_skip_step(self):
- self._continue_node_deploy_skip_step()
-
- def test_continue_node_deploy_no_skip_step(self):
- self._continue_node_deploy_skip_step(skip=False)
-
- @mock.patch('ironic.conductor.manager.ConductorManager._spawn_worker',
- autospec=True)
- def test_continue_node_deploy_polling(self, mock_spawn):
- # test that deployment_polling flag is cleared
- driver_info = {'deploy_steps': self.deploy_steps,
- 'deploy_step_index': 0,
- 'deployment_polling': True,
- 'steps_validated': True}
- node = obj_utils.create_test_node(
- self.context, driver='fake-hardware',
- provision_state=states.DEPLOYWAIT,
- target_provision_state=states.MANAGEABLE,
- driver_internal_info=driver_info, deploy_step=self.deploy_steps[0])
- self._start_service()
- self.service.continue_node_deploy(self.context, node.uuid)
- self._stop_service()
- node.refresh()
- self.assertNotIn('deployment_polling', node.driver_internal_info)
- mock_spawn.assert_called_with(mock.ANY,
- deployments.do_next_deploy_step,
- mock.ANY, 1)
-
- @mock.patch.object(conductor_steps, 'validate_deploy_templates',
- autospec=True)
- @mock.patch('ironic.conductor.manager.ConductorManager._spawn_worker',
- autospec=True)
- def test_continue_node_steps_validation(self, mock_spawn, mock_validate):
- prv_state = states.DEPLOYWAIT
- tgt_prv_state = states.ACTIVE
- mock_validate.side_effect = exception.InvalidParameterValue('boom')
- driver_info = {'deploy_steps': self.deploy_steps,
- 'deploy_step_index': 0,
- 'steps_validated': False}
- node = obj_utils.create_test_node(self.context, driver='fake-hardware',
- provision_state=prv_state,
- target_provision_state=tgt_prv_state,
- last_error=None,
- driver_internal_info=driver_info,
- deploy_step=self.deploy_steps[0])
- self._start_service()
- mock_spawn.reset_mock()
- self.service.continue_node_deploy(self.context, node.uuid)
- self._stop_service()
- node.refresh()
- self.assertEqual(states.DEPLOYFAIL, node.provision_state)
- self.assertIn('Failed to validate the final deploy steps',
- node.last_error)
- self.assertIn('boom', node.last_error)
- self.assertEqual(tgt_prv_state, node.target_provision_state)
- self.assertFalse(mock_spawn.called)
-
@mgr_utils.mock_record_keepalive
class CheckTimeoutsTestCase(mgr_utils.ServiceSetUpMixin, db_base.DbTestCase):
@@ -2627,13 +2506,10 @@ class DoNodeCleanTestCase(mgr_utils.ServiceSetUpMixin, db_base.DbTestCase):
# test a node can continue cleaning via RPC
prv_state = return_state
tgt_prv_state = states.MANAGEABLE if manual else states.AVAILABLE
- driver_info = {'clean_steps': self.clean_steps,
- 'clean_step_index': 0}
node = obj_utils.create_test_node(self.context, driver='fake-hardware',
provision_state=prv_state,
target_provision_state=tgt_prv_state,
last_error=None,
- driver_internal_info=driver_info,
clean_step=self.clean_steps[0])
self._start_service()
self.service.continue_node_clean(self.context, node.uuid)
@@ -2642,8 +2518,7 @@ class DoNodeCleanTestCase(mgr_utils.ServiceSetUpMixin, db_base.DbTestCase):
self.assertEqual(states.CLEANING, node.provision_state)
self.assertEqual(tgt_prv_state, node.target_provision_state)
mock_spawn.assert_called_with(self.service,
- cleaning.do_next_clean_step,
- mock.ANY, self.next_clean_step_index)
+ cleaning.continue_node_clean, mock.ANY)
def test_continue_node_clean_automated(self):
self._continue_node_clean(states.CLEANWAIT)
@@ -2651,60 +2526,6 @@ class DoNodeCleanTestCase(mgr_utils.ServiceSetUpMixin, db_base.DbTestCase):
def test_continue_node_clean_manual(self):
self._continue_node_clean(states.CLEANWAIT, manual=True)
- @mock.patch('ironic.conductor.manager.ConductorManager._spawn_worker',
- autospec=True)
- def _continue_node_clean_skip_step(self, mock_spawn, skip=True):
- # test that skipping current step mechanism works
- driver_info = {'clean_steps': self.clean_steps,
- 'clean_step_index': 0}
- if not skip:
- driver_info['skip_current_clean_step'] = skip
- node = obj_utils.create_test_node(
- self.context, driver='fake-hardware',
- provision_state=states.CLEANWAIT,
- target_provision_state=states.MANAGEABLE,
- driver_internal_info=driver_info, clean_step=self.clean_steps[0])
- self._start_service()
- self.service.continue_node_clean(self.context, node.uuid)
- self._stop_service()
- node.refresh()
- if skip:
- expected_step_index = 1
- else:
- self.assertNotIn(
- 'skip_current_clean_step', node.driver_internal_info)
- expected_step_index = 0
- mock_spawn.assert_called_with(self.service,
- cleaning.do_next_clean_step,
- mock.ANY, expected_step_index)
-
- def test_continue_node_clean_skip_step(self):
- self._continue_node_clean_skip_step()
-
- def test_continue_node_clean_no_skip_step(self):
- self._continue_node_clean_skip_step(skip=False)
-
- @mock.patch('ironic.conductor.manager.ConductorManager._spawn_worker',
- autospec=True)
- def test_continue_node_clean_polling(self, mock_spawn):
- # test that cleaning_polling flag is cleared
- driver_info = {'clean_steps': self.clean_steps,
- 'clean_step_index': 0,
- 'cleaning_polling': True}
- node = obj_utils.create_test_node(
- self.context, driver='fake-hardware',
- provision_state=states.CLEANWAIT,
- target_provision_state=states.MANAGEABLE,
- driver_internal_info=driver_info, clean_step=self.clean_steps[0])
- self._start_service()
- self.service.continue_node_clean(self.context, node.uuid)
- self._stop_service()
- node.refresh()
- self.assertNotIn('cleaning_polling', node.driver_internal_info)
- mock_spawn.assert_called_with(self.service,
- cleaning.do_next_clean_step,
- mock.ANY, 1)
-
def _continue_node_clean_abort(self, manual=False):
last_clean_step = self.clean_steps[0]
last_clean_step['abortable'] = False