I am trying to use set_fact
with until
and retries
, will the fact be evaluated and set during each iteration ? Sometimes I see the value is not being set and I get the failure after the retries. While I see the corresponding lookup returns value using another cli.
Yes. The the fact will be evaluated and set on each iteration. The problem is
that "set_fact" declares the variable "che_keycloak". The condition
until: che_keycloak.spec is defined
can't find the parameter "spec" because there isn't any.
Cheers,
-vlado
I am trying to use
set_fact
withuntil
andretries
, will the fact be
evaluated and set during each iteration ? Sometimes I see the value is not
being set and I get the failure after the retries. While I see the
corresponding lookup returns value using another cli.
- name: “Get Che Keycloak facts”
set_fact:
che_keycloak:
“{{ lookup(‘k8s’, api_version=‘route.openshift.io/v1’,kind=‘Route’,resource_name=‘keycloak’,namespace=‘che’) }}”
register: che_keycloak_route_result
until: che_keycloak.spec is defined
retries: 30
delay: 10
when: state == ‘present’Yes. The the fact will be evaluated and set on each iteration. The problem is
that “set_fact” declares the variable “che_keycloak”. The conditionuntil: che_keycloak.spec is defined
can’t find the parameter “spec” because there isn’t any.
do you mean to say I should invert the condition for this logic to work ?
Take a look at the registered variable "che_keycloak_route_result" to see
what's going on
- debug:
var: che_keycloak_route_result
Cheers,
-vlado
No. I simply mean "spec" is not defined. The question is why? Take a look at
the registered variable. This should provide you with this information.
Cheers,
-vlado
Yes. The the fact will be evaluated and set on each iteration. The problem
is
that “set_fact” declares the variable “che_keycloak”. The conditionuntil: che_keycloak.spec is defined
can’t find the parameter “spec” because there isn’t any.
do you mean to say I should invert the condition for this logic to work ?
No. I simply mean “spec” is not defined. The question is why? Take a look at
the registered variable. This should provide you with this information.
the spec becomes available only after few seconds; so I need to keep the lookup run until then. Thats why I had that until checking to see if spec is defined in the fact.
What is the failure (copy&paste) that "Sometimes I see the value is not being
set and I get the failure after the retries."?
that “set_fact” declares the variable “che_keycloak”. The condition
until: che_keycloak.spec is defined
can’t find the parameter “spec” because there isn’t any.
do you mean to say I should invert the condition for this logic to work ?
No. I simply mean “spec” is not defined. The question is why? Take a look
the registered variable. This should provide you with this information.the spec becomes available only after few seconds; so I need to keep the
lookup run until then. Thats why I had that until checking to see if spec
is defined in the fact.What is the failure (copy&paste) that “Sometimes I see the value is not being
set and I get the failure after the retries.”?
Exactly I see the value is not being set inspite of that is available after few seconds . The failure throws an error like
“fatal: [localhost]: FAILED! => {“ansible_facts”: {“che_keycloak”: }, “attempts”: 30, “changed”: false}”
OK. Set "ignore_errors: true", register and print "result". Post it.
- set_fact:
che_keycloak: "{{ lookup('k8s',
api_version='route.openshift.io/v1',
kind='Route',
resource_name='keycloak',
namespace='che') }}"
register: result
until: che_keycloak.spec is
defined retries: 30 delay: 10
ignore_errors: true
when: state == 'present'
- debug:
var: result
Fixed syntax.
With set_fact and until it will not set the variable on each iteration unfortunately.
I don't know of any workaround.
I am trying to use
set_fact
withuntil
andretries
, will the fact
be
evaluated and set during each iteration ? Sometimes I see the value is
not
being set and I get the failure after the retries. While I see the
corresponding lookup returns value using another cli.
- name: “Get Che Keycloak facts”
set_fact:
che_keycloak:
“{{ lookup(‘k8s’,
api_version=‘route.openshift.io/v1’,kind=‘Route’,resource_name=‘keycloak’,namespace=‘che’)
}}”
register: che_keycloak_route_result
until: che_keycloak.spec is defined
retries: 30
delay: 10
when: state == ‘present’With set_fact and until it will not set the variable on each iteration
unfortunately.
That is what I observe
I don’t know of any workaround.
any other better way you think of doing my task?
You can add the pause module and just wait long enough.
I have not used the Kubernetes, but if it's a k8s module or and API with URI module that can do the same, that with register would function with until.
The "lookup" plugin is evaluated only once before the module starts [1].
Hence it's not possible to get it working with the until/retries construct.
FWIW, it is possible to put it together. The "brute-force" playbook below
- hosts: localhost
vars:
my_continue: true
my_delay: 10
my_retries: 5
tasks:
- include_tasks: include-lookup.yml
loop: "{{ range(0, my_retries)|list }}"
with the included file include-lookup.yml
- name: 'Get data'
set_fact:
my_var: "{{ lookup('pipe', '/scratch/tmp/my_script')|from_yaml }}"
when: my_continue
- name: 'Set continue=false when data OK'
set_fact:
my_continue: false
when:
- my_var.spec is defined
- my_continue
- name: 'Delay next iteration'
wait_for:
timeout: "{{ my_delay }}"
when: my_continue
does the job. The concept works. When the variable "my_var.spec" is defined
then the variable "continue" will be set to False and following tasks will be
skipped.
[1] The "lookup" plugin is evaluated only once before the module starts. From
the log written by "my_script" cat be seen that "lookup" is evaluated
only once.
tasks:
- shell: "echo {{ lookup('pipe', '/scratch/tmp/my_script') }}"
# - shell: "/scratch/tmp/my_script"
ignore_errors: true
register: result
until: result.stdout == 'DUMMY'
retries: 3
delay: 2
$ cat my_script
#!/bin/sh
my_data=/scratch/tmp/my_data
my_log=/scratch/tmp/my_script.log
if [ -e ${my_data} ]; then
cat ${my_data}
fi
date >> ${my_log}
$ cat my_data
spec: 'Specification'
HTH. Cheers,
- vlado
That seems overly complex. I would instead wait until the required data is available before running set_fact:
`
-
vars:
che_keycloak_lookup: “{{ lookup(‘k8s’, api_version=‘route.openshift.io/v1’,kind=‘Route’,resource=‘keycloak’,namespace='che’) }}”
block: -
debug:
msg: Waiting for data propagation…
until: “‘spec’ in che_keycloak_lookup”
retries: 30
delay: 10 -
name: Get Che Keycloak facts
set_fact:
che_keycloak: “{{ che_keycloak_lookup }}”
`
Great! This is the solution how to evaluate "lookup" in each iteration. Just
put the evaluation into "until".
Thank you,
-vlado
Thank you Vladmir and flowerysong, this solution works just as its needed.