-
Notifications
You must be signed in to change notification settings - Fork 23.7k
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
Feature: Allow until-loops on blocks or includes #46203
Comments
@mkrizek Hmm, I searched for various combination of keywords, and that one did not stick out :-( That said, I tried using - hosts: localhost
tasks:
- include: taskboot.yml
until: 5|random == 5 But apparently looping only works when using - hosts: localhost
tasks:
- include: taskboot.yml
loop: [ 1, 2, 3, 4, 5 ] |
Whatever I try, using - hosts: localhost
tasks:
- include: taskbook.yml
until: false
retries: 5
delay: 1 |
Yeah, |
@mkrizek In other words, what we need is not possible, neither on blocks or on includes. So I will keep this one open, but changed the title. |
We do have an open proposal to "taskify" includes, which would allow things like until to work on them. I, however, do not believe that blocks should be extended to support this feature. |
@sivel And what would be the reason for not extending the functionality to blocks ? As it would be a natural thing if it would work. (i.e. being able to loop every construction within a play) |
blocks are currently 'static' groupings, enabling loops on them (not just having tasks inherit them) would require making them dynamic ... as we saw with |
To extend what @bcoca mentions, doing so would require us to deprecate Also, every user of ansible utilizes blocks, whether explicit, or our internal implicit use of them. They are a fundamental building block of how tasks are represented and executed. Changing such an integral feature is sure to lead to unforeseen issues. |
In any case, the documentation does not give any detail, or even does not discuss what is supposed to work and what not. There's no real distinction between "loops" and until-loops, not sure how we can make this more clear overal. The expectation is that what works for "loops" also works for until-loops. |
i would do both, allow until/retry loops to work with includes and then clearly document how they work ... so we have something to point at when it does not meet some people's expectations |
Just to provide a small amount of detail about how includes work, is that dynamic includes are more of an internal trigger, as opposed to something that wraps execution. As such, the task_executor short circuits early on an include, indicating to the strategy that it should read a file and insert task blocks into the TQM, that will later be processed by the task_executor. Due to this, there is no tracking of state as a roll up to the parent include. So an until loop, which would rely on some version of a failed when/success scenario, would only refer to whether or not the strategy was told to do as detailed above. In which case, it should always succeed. In any case, the mode of operation is that we short circuit far before an until conditions are inspected. If we just "made it work" right now, it definitely wouldn't do what a person expects. To do what people expect, would require ansible/proposals#136 to be implemented. |
the until in this case would have to rely on vars set or registered from the included tasks as the registration of the include itself would be useless ... it would still 'work' just not how most other cases do. |
@dagwieers The other thread is locked now. But this recent suggestion (@sivel comment above) is brand new: And you are saying we might want to leave open the possibility of someone else coming along later, to do a PR for looping over blocks off their own backs. Then at least we could make it crystal clear to them, as to make it as a separate and new |
Linking this here #16621 |
This comment has been minimized.
This comment has been minimized.
It is natural that a block should be repeatable. Otherwise, it is very counterintuitive. It confuses. And there seems to be no way to write a playbook with loop with more than one statement. No programming language is so limited. |
It looks like in Ansible, if one needs to do something complex, one should write an action plugin. This is what we are going to do. Here one has many examples: Best regards |
This is absolutely a shortcoming. Ansible has been perfect for most of my needs so far, but it seems like expanding the capabilities of blocks would make Ansible a lot better solution. |
I tried to use What I did as a workaround was to create a yml file that include the task ( recursive.yml: ---
- name: 'checking {{ watch_job }} status (recursive)'
include_tasks: 'loop.yml'
- name: 'count ({{ watch_count | int + 1 }})'
set_fact:
watch_count: '{{ watch_count | int + 1 }}'
- name: 'retries ({{ (watch_timeout | int / watch_poll | int) | int }})'
set_fact:
watch_retries: '{{ (watch_timeout | int / watch_poll | int) | int }}'
- name: 'timeout ({{ watch_timeout }} seconds)'
fail:
msg: "Timeout of {{ watch_timeout }} seconds exceeded ({{ watch_retries }} retries)"
when: (not watch_status.finished) and (watch_count | int > watch_retries | int)
- name: 'wait for {{ watch_poll }} seconds'
wait_for:
timeout: '{{ watch_poll | int }}'
when: not watch_status.finished
- name: 'call itself recursively'
include_tasks: 'recursive.yml'
when: not watch_status.finished In the above file, I included a timeout in the case of taking too long (this is in a role that shows the output of what is running in the hosts). Not the ideal solution, but worked for me and was relatively easy to change using |
+1 for this feature ! |
+1 |
+1 for until loops on blocks |
I have been searching a way to do I could not use regular
|
Same as @matanbaru with a way to fail after multiple retries - name: 'Wait until success'
block:
- name: Set the retry count
set_fact:
retry_count: "{{ 0 if retry_count is undefined else retry_count|int + 1 }}"
- name: Get server updated ip
uri:
url: https://localhost/ip
return_content: yes
status_code: 200
register: ip
- name: ssh to the server
wait_for:
host: "{{ ip }}"
port: 22
timeout: 30
state: started
rescue:
- fail:
msg: Ended after 5 retries
when: retry_count|int == 5
- debug:
msg: "Failed to connect - Retrying..."
- include_tasks: wait_until_success.yml |
+1 could you please add retry-until in loops ! |
+1 |
+1 |
I've locked this to contributors for now. Adding |
Thank you very much for your submission to Ansible. It means a lot to us that you've taken time to contribute. Unfortunately, this issue has been open for some time while waiting for a contributor to take it up but there does not seem to have been anyone that did so. So we are going to close this issue to clear up the queues and make it easier for contributors to browse possible implementation targets. However, we're absolutely always up for discussion. Because this project is very active, we're unlikely to see comments made on closed tickets and we lock them after some time. If you or anyone else has any further questions, please let us know by using any of the communication methods listed in the page below: In the future, sometimes starting a discussion on the development list prior to proposing or implementing a feature can make getting things included a little easier, but it's not always necessary. Thank you once again for this and your interest in Ansible! |
SUMMARY
It would be quite useful if you can loop over more than one single tasks.
For instance if you have to poll a remote system for some progress and at the same time you want to push this progress to another backend, you could be doing:
There are many uses to this.
ISSUE TYPE
COMPONENT NAME
Core
The text was updated successfully, but these errors were encountered: