mirror of
https://github.com/ansible/ansible.git
synced 2026-08-02 00:22:14 +02:00
* Fix IndexError in free strategy when hosts become unreachable
Fixes an IndexError crash in the free strategy plugin when hosts
become unreachable during playbook execution.
The bug occurred when:
- last_host index persists across outer loop iterations
- hosts_left is regenerated each iteration via get_hosts_left()
- Some hosts become unreachable between iterations
- hosts_left shrinks but last_host retains its previous value
- Accessing hosts_left[last_host] raises IndexError
The fix adds a bounds check after regenerating hosts_left to reset
last_host to 0 if it's out of bounds. This preserves the round-robin
fairness algorithm while preventing the IndexError.
Assisted-by: Claude Sonnet 4.5 <noreply@anthropic.com>
* integration test
* review comment fixes
* ci_complete
(cherry picked from commit 08a71d148e)
This commit is contained in:
@@ -0,0 +1,2 @@
|
|||||||
|
bugfixes:
|
||||||
|
- free strategy - Fix ``IndexError`` when hosts become unreachable during playbook execution (https://github.com/ansible/ansible/issues/87027).
|
||||||
@@ -92,6 +92,11 @@ class StrategyModule(StrategyBase):
|
|||||||
result = False
|
result = False
|
||||||
break
|
break
|
||||||
|
|
||||||
|
# Reset last_host if it's out of bounds for the current hosts_left
|
||||||
|
# This can happen when hosts become unreachable between iterations
|
||||||
|
if last_host >= len(hosts_left):
|
||||||
|
last_host = 0
|
||||||
|
|
||||||
work_to_do = False # assume we have no more work to do
|
work_to_do = False # assume we have no more work to do
|
||||||
starting_host = last_host # save current position so we know when we've looped back around and need to break
|
starting_host = last_host # save current position so we know when we've looped back around and need to break
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
[local]
|
||||||
|
host0 ansible_connection=local ansible_python_interpreter="{{ ansible_playbook_python }}"
|
||||||
|
host1 ansible_connection=ssh ansible_host=127.0.0.1 ansible_port=1011 # IANA Reserved port
|
||||||
|
host2 ansible_connection=local ansible_python_interpreter="{{ ansible_playbook_python }}"
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
---
|
||||||
|
- hosts: host0, host1, host2
|
||||||
|
strategy: free
|
||||||
|
gather_facts: false
|
||||||
|
tasks:
|
||||||
|
- name: EXPECTED FAILURE - First ping
|
||||||
|
ping:
|
||||||
|
throttle: 2
|
||||||
|
|
||||||
|
- name: Second ping
|
||||||
|
ping:
|
||||||
@@ -8,3 +8,9 @@ set +e
|
|||||||
result="$(ansible-playbook test_last_include_in_always.yml -i inventory "$@" 2>&1)"
|
result="$(ansible-playbook test_last_include_in_always.yml -i inventory "$@" 2>&1)"
|
||||||
set -e
|
set -e
|
||||||
grep -q "INCLUDED TASK EXECUTED" <<< "$result"
|
grep -q "INCLUDED TASK EXECUTED" <<< "$result"
|
||||||
|
|
||||||
|
set +e
|
||||||
|
result="$(ansible-playbook free_index_error.yml -i free_hosts "$@" 2>&1)"
|
||||||
|
set -e
|
||||||
|
grep -q "\[host1\]: UNREACHABLE!" <<< "$result"
|
||||||
|
! grep -q "IndexError: list index out of range" <<< "$result"
|
||||||
|
|||||||
Reference in New Issue
Block a user