diff --git a/ironic/db/sqlalchemy/api.py b/ironic/db/sqlalchemy/api.py index e3f62335f2..e8f4c737a9 100644 --- a/ironic/db/sqlalchemy/api.py +++ b/ironic/db/sqlalchemy/api.py @@ -564,7 +564,7 @@ class Connection(api.Connection): @oslo_db_api.retry_on_deadlock def destroy_node(self, node_id): - with _session_for_write(): + with _session_for_write() as session: query = model_query(models.Node) query = add_identity_filter(query, node_id) @@ -573,6 +573,11 @@ class Connection(api.Connection): except NoResultFound: raise exception.NodeNotFound(node=node_id) + # Orphan allocation, if any. On the API level this is only allowed + # with maintenance on. + node_ref.allocation_id = None + node_ref.save(session) + # Get node ID, if an UUID was supplied. The ID is # required for deleting all ports, attached to the node. if uuidutils.is_uuid_like(node_id): diff --git a/ironic/tests/unit/db/test_nodes.py b/ironic/tests/unit/db/test_nodes.py index ba98840199..2ca7eb5e9e 100644 --- a/ironic/tests/unit/db/test_nodes.py +++ b/ironic/tests/unit/db/test_nodes.py @@ -595,6 +595,8 @@ class DbNodeTestCase(base.DbTestCase): node = utils.create_test_node() allocation = utils.create_test_allocation(node_id=node.id) + node = self.dbapi.update_node(node.id, + {'allocation_id': allocation.id}) self.dbapi.destroy_node(node.uuid) self.assertRaises(exception.AllocationNotFound, diff --git a/releasenotes/notes/allocation-delete-26c7c2f1651759f5.yaml b/releasenotes/notes/allocation-delete-26c7c2f1651759f5.yaml new file mode 100644 index 0000000000..0973a725e8 --- /dev/null +++ b/releasenotes/notes/allocation-delete-26c7c2f1651759f5.yaml @@ -0,0 +1,6 @@ +--- +fixes: + - | + Fixes deleting nodes with maintenance mode on and an allocation present. + Previously it caused an internal server error. See `story 2007823 + `_ for details.