diff options
author | Jenkins <jenkins@review.openstack.org> | 2016-03-21 09:39:39 +0000 |
---|---|---|
committer | Gerrit Code Review <review@openstack.org> | 2016-03-21 09:39:39 +0000 |
commit | 57955083471cab657ce023d13f597cb35e1adc3d (patch) | |
tree | 98f21f9acb2ff4a9af93d89adfb75ab8755082d5 | |
parent | ea238dcffa2a415c2ac40ee0f42977b1bfc0b1a1 (diff) | |
parent | aa4d3fa0220450517bebd621b6db0f8ca1fba0ca (diff) | |
download | ironic-57955083471cab657ce023d13f597cb35e1adc3d.tar.gz |
Merge "Make sure target state is cleared on stable states"
-rw-r--r-- | ironic/common/states.py | 10 | ||||
-rw-r--r-- | ironic/conductor/task_manager.py | 9 | ||||
-rw-r--r-- | ironic/tests/unit/conductor/test_manager.py | 2 | ||||
-rw-r--r-- | ironic/tests/unit/conductor/test_task_manager.py | 22 | ||||
-rw-r--r-- | releasenotes/notes/clear-target-stable-states-4545602d7aed9898.yaml | 5 |
5 files changed, 41 insertions, 7 deletions
diff --git a/ironic/common/states.py b/ironic/common/states.py index 721cbc4e3..09c4aff85 100644 --- a/ironic/common/states.py +++ b/ironic/common/states.py @@ -176,6 +176,9 @@ UPDATE_ALLOWED_STATES = (DEPLOYFAIL, INSPECTING, INSPECTFAIL, CLEANFAIL, ERROR, DELETE_ALLOWED_STATES = (AVAILABLE, NOSTATE, MANAGEABLE, ENROLL) """States in which node deletion is allowed.""" +STABLE_STATES = (ENROLL, MANAGEABLE, AVAILABLE, ACTIVE, ERROR) +"""States that will not transition unless receiving a request.""" + ############## # Power states @@ -212,11 +215,8 @@ watchers['on_enter'] = on_enter machine = fsm.FSM() # Add stable states -machine.add_state(ENROLL, stable=True, **watchers) -machine.add_state(MANAGEABLE, stable=True, **watchers) -machine.add_state(AVAILABLE, stable=True, **watchers) -machine.add_state(ACTIVE, stable=True, **watchers) -machine.add_state(ERROR, stable=True, **watchers) +for state in STABLE_STATES: + machine.add_state(state, stable=True, **watchers) # Add verifying state machine.add_state(VERIFYING, target=MANAGEABLE, **watchers) diff --git a/ironic/conductor/task_manager.py b/ironic/conductor/task_manager.py index a520816e3..a136c27e3 100644 --- a/ironic/conductor/task_manager.py +++ b/ironic/conductor/task_manager.py @@ -382,7 +382,14 @@ class TaskManager(object): self.node.target_provision_state) self.node.provision_state = self.fsm.current_state - self.node.target_provision_state = self.fsm.target_state + + # NOTE(lucasagomes): If there's no extra processing + # (callback) and we've moved to a stable state, make sure the + # target_provision_state is cleared + if not callback and self.fsm.is_stable(self.node.provision_state): + self.node.target_provision_state = states.NOSTATE + else: + self.node.target_provision_state = self.fsm.target_state # set up the async worker if callback: diff --git a/ironic/tests/unit/conductor/test_manager.py b/ironic/tests/unit/conductor/test_manager.py index 75eb0f40f..48cf4c038 100644 --- a/ironic/tests/unit/conductor/test_manager.py +++ b/ironic/tests/unit/conductor/test_manager.py @@ -1120,7 +1120,7 @@ class DoNodeDeployTearDownTestCase(mgr_utils.ServiceSetUpMixin, self.service._do_node_tear_down, task) node.refresh() self.assertEqual(states.ERROR, node.provision_state) - self.assertEqual(states.AVAILABLE, node.target_provision_state) + self.assertEqual(states.NOSTATE, node.target_provision_state) self.assertIsNotNone(node.last_error) # Assert instance_info was erased self.assertEqual({}, node.instance_info) diff --git a/ironic/tests/unit/conductor/test_task_manager.py b/ironic/tests/unit/conductor/test_task_manager.py index 758edf3f3..6c6bac1d4 100644 --- a/ironic/tests/unit/conductor/test_task_manager.py +++ b/ironic/tests/unit/conductor/test_task_manager.py @@ -625,6 +625,28 @@ class TaskManagerStateModelTestCases(tests_base.TestCase): self.assertNotEqual(target_provision_state, self.node.target_provision_state) + def test_process_event_callback_stable_state(self): + callback = mock.Mock() + for state in states.STABLE_STATES: + self.node.provision_state = state + self.node.target_provision_state = 'target' + self.task.process_event = task_manager.TaskManager.process_event + self.task.process_event(self.task, 'fake', callback=callback) + # assert the target state is set when callback is passed + self.assertNotEqual(states.NOSTATE, + self.task.node.target_provision_state) + + def test_process_event_no_callback_stable_state(self): + for state in states.STABLE_STATES: + self.node.provision_state = state + self.node.target_provision_state = 'target' + self.task.process_event = task_manager.TaskManager.process_event + self.task.process_event(self.task, 'fake') + # assert the target state was cleared when moving to a + # stable state + self.assertEqual(states.NOSTATE, + self.task.node.target_provision_state) + @task_manager.require_exclusive_lock def _req_excl_lock_method(*args, **kwargs): diff --git a/releasenotes/notes/clear-target-stable-states-4545602d7aed9898.yaml b/releasenotes/notes/clear-target-stable-states-4545602d7aed9898.yaml new file mode 100644 index 000000000..e5bac700d --- /dev/null +++ b/releasenotes/notes/clear-target-stable-states-4545602d7aed9898.yaml @@ -0,0 +1,5 @@ +--- +fixes: + - Ensure node's target_provision_state is cleared when the node + is moved to a stable state, indicating that the state transition + is done. |