New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Prevent reparenting a block with itself #36075
Conversation
1ce29cd
to
b8c190d
Compare
This PR does not address recursion errors when using nested includes (eg a->b->c->d...) as opposed to a flat playbook/task file with many includes. They have the same traceback, but different causes. In the nested include scenario, we should have that many parents, we just cannot copy all of the objects. Eventually we hit a recursion error. |
FWIW, I tested a recursive include that made it over 250 levels deep before hitting a python recursion error, so hopefully no-one goes to that extreme with nested includes... |
* Prevent reparenting a block with itself * Move __eq__ to Block, to avoid some unexpected problems (cherry picked from commit 76ff3e9)
* Prevent reparenting a block with itself * Move __eq__ to Block, to avoid some unexpected problems (cherry picked from commit 76ff3e9)
Since this is changing how some of the playbook objects compares work, I updated a branch with some playbook object compare tests at #36132 if it would be helpful for testing. |
SUMMARY
We have been noticing that the parent tree for blocks is mutated and grows to large sizes. We have partially mitigated the problem in previous changes, but as a result the number of dynamic includes was limited in number due to recursion errors.
This change ensures that we never reparent a block with itself, causing a block explosion and recursion errors.
This also drastically speeds up dynamic task includes over time.
ISSUE TYPE
COMPONENT NAME
lib/ansible/playbook/base.py
lib/ansible/playbook/block.py
ANSIBLE VERSION
ADDITIONAL INFORMATION
Output of parent lineage from
Strategy._load_included_file
during a successive 100include_tasks
s in a flat playbook (reproducer from #36053):Before this change (failing on the 42nd):
After this change (executes all 100
include_task
s):