with_sequence is incompatible with idempotency

379 views
Skip to first unread message

Kesten Broughton

unread,
Apr 30, 2014, 9:34:07 AM4/30/14
to ansible...@googlegroups.com

I recently had a need for with_sequence, but it doesn't seem possible to do a zero count of actions.

Suppose i have a local action to create N things, perhaps vms or floating ips.  Some number M < N may already be present.

I'd like to do
 
hosts: localhost
vars:
   expected_foo_count: 10

 - name: Get the number of foos
   shell: echo M
   register: foo_count

 - name: Create the missing number of foos
   shell: make_new_foos
   with_sequence: start=0 end="{{expected_foo_count -foo_count.stdout }}"

or  with_sequence: count="{{expected_foo_count - foo_count.stdout}}"
 
This will work if M is strictly less than N, but if M=N (the idempotent case) then ansible gives an error.

fatal: [localhost] => can't count backwards

I tried putting a "when" guard such as
 when: "{{ expected_foo_count - foo_count.stdout > 0 }}"

But it appears "when" gets evaluated after the with_sequence conditional.  That in itself poses problems, since in branching code the register variables may not be defined and you have to litter code with when: "{{ (register_var or '') | conditional }}".

The problem with the with_sequence is in the lib/ansible/runner/lookup_plugins/sequence.py

    def generate_sequence(self):
        numbers = xrange(self.start, self.end+1, self.stride)

which means that contrary to conventional python such as
range(a,b) which gives a sequence starting at 'a' and ending at 'b-1', ie. [a,b)  

with_sequence: start=n end=m

runs over the sequence [n,m].  If n=m with_sequence still executes once, so there is no possible way to have a with_sequence that runs zero times.

changing the generate_sequence code to
   
    def generate_sequence(self):
        numbers = xrange(self.start, self.end, self.stride)

Fixes the problem.

Is there a design reason behind not allowing for zero count sequences?  If so, how can a playbook including with_sequence be made idempotent?

kesten

Michael DeHaan

unread,
Apr 30, 2014, 4:03:56 PM4/30/14
to ansible...@googlegroups.com
You are throwing two words together that have nothing to do with each other.

with_sequence is a loop.

Idempotency is a mathematical statement that says "F(X) = F(F(X))" for how many times X is applied.   

"This will work if M is strictly less than N, but if M=N (the idempotent case) then ansible gives an error."

What you have here is Ansible giving an error.  It has nothing to do with idempotency.

It may imply "with sequence can't traverse a zero length list", which more accurately describes the problem.

So, the best thing to do here is to share what the error is and we can go from there.






--
You received this message because you are subscribed to the Google Groups "Ansible Project" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ansible-proje...@googlegroups.com.
To post to this group, send email to ansible...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/ansible-project/CAO2fFsVLwC6qoVKReu--zjyfOwUA1KUJQWy2cG36nmHRietk0g%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

kesten broughton

unread,
Apr 30, 2014, 5:51:12 PM4/30/14
to ansible...@googlegroups.com
The error is
fatal: [localhost] => can't count backwards

This occurs whenever count=0 or start=M end=M

If with_sequence is used for the purpose of bringing a system to a state = HAS N of something
then there should be a way of running the playbook twice and not having anything new created.
That's what i meant by idempotent.

 "with sequence can't traverse a zero length list" accurately describes my concern

kesten

Philippe Eveque

unread,
May 1, 2014, 3:32:23 AM5/1/14
to ansible...@googlegroups.com
In similar case A workaround I used  is to add 1 to your sequence count
see https://mail.google.com/mail/#search/label%3Aansible+with_sequence/1435e13b34e3a0e1

Phil


kesten broughton

unread,
May 1, 2014, 9:34:41 AM5/1/14
to ansible...@googlegroups.com
Phil, the link doesn't work for me.

Philippe Eveque

unread,
May 1, 2014, 3:17:05 PM5/1/14
to ansible...@googlegroups.com
The link references a previous exchange similar to yours

The specific case was about using the lineinfile module and with_sequence
to add a parameter to all the kernel liles in grub.conf

here is a copy of what I wrote:

"
tasks 1: count the number of lines to replace (via shell module using and grep -E <regexp> | wc -l )
 using register to remember the linecounted

task 2: using lineinfile and with_sequence: linecounted

one caveat is that with sequence does not accept a 0 count ( a potential future improvement ?)

so just add  1 to the count (you do not care about doing it one more time)

then you can run those 2 tasks multiples times

works for me on grub.conf
"


Phil


kesten broughton

unread,
May 1, 2014, 3:44:55 PM5/1/14
to ansible...@googlegroups.com
ah, thanks phillippe.

I think in my case this won't work since i DO care about doing it one more time.
The thing i'm doing is creating vms.  But i don't want to create 1 more if i already have my desired N.

k


--
You received this message because you are subscribed to a topic in the Google Groups "Ansible Project" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/ansible-project/swkbKGLio1g/unsubscribe.
To unsubscribe from this group and all its topics, send an email to ansible-proje...@googlegroups.com.

To post to this group, send email to ansible...@googlegroups.com.

Philippe Eveque

unread,
May 1, 2014, 3:52:23 PM5/1/14
to ansible...@googlegroups.com
sure !
So being able to traverse a zero length list would fix yours issue
and avoid the need for my workaround


Phil


Michael DeHaan

unread,
May 1, 2014, 5:32:17 PM5/1/14
to ansible...@googlegroups.com
So it seems easiest to just make it so it can create zero length lists.

Please make sure there's a github ticket and this can be dealt with.

Tickets go here:  github.com/ansible/ansible

(Fix pull requests are even better)

Thanks!






Reply all
Reply to author
Forward
0 new messages