Calculating with Variables?

206 views
Skip to first unread message

Ulrich Hochholdinger

unread,
Jan 3, 2015, 8:02:04 PM1/3/15
to ansible...@googlegroups.com
Hi,
I just started playing around with ansible and tried to achieve a simple operations task with it:

Iterate over all nodes of my Xen-Cluster -- get free_memory of every node and sum up those values.
next step would be making a decision e.g. spawning a new VM without overprovisioning the cluster.

So I wrote a simple module which collects "xm info" values as ansible_facts. This was easy...

Next step: write a playbook which sums up one of the collected fact (free_memory) -- here I got stuck and have no more ideas how to solve this...

This is a not working idea:

# vim:ft=ansible:
---
- hosts: Cluster
  vars:
 # should be initially set to zero??
    sum_free_memory: "{{ sum_free_memory|int + xm_infos.free_memory|int }}"
  tasks:
    - name: gather xen facts
      xm_info:

    - name: show free_memory on host
      debug: msg="{{ xm_infos.free_memory|int }}"

    - name: increment sum_free_memory
      debug: msg="{{ sum_free_memory|int }}"

=> which obviously doesn't work:
ERROR: recursive loop detected in template string: {{ sum_free_memory|int + xm_infos.free_memory|int }}

So how can I sum up collected facts from more than one host?

Cheers
      Ulli


Tom Bamford

unread,
Jan 5, 2015, 8:49:05 AM1/5/15
to ansible...@googlegroups.com

Hi Ulrich

How about a ‘for’ loop (in Jinja2) contained as a parameter to the set_fact module, iterating the facts you gathered as presented in the {{ hostvars }} magic variable?

Regards
Tom

--
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/85495348-c277-40f4-ac7a-bade124f02c6%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Michael DeHaan

unread,
Jan 5, 2015, 9:10:17 AM1/5/15
to ansible...@googlegroups.com
for loops in Jinja2 can't be used (with any definition of sanity) in Ansible playbooks.

They can be used in templates used by the template module.

Let's step back a moment...

Can you remove the recursive reference and just call it "actual_free_mem" or something, and see where you are from there.






Ulrich Hochholdinger

unread,
Jan 5, 2015, 7:26:53 PM1/5/15
to ansible...@googlegroups.com
Hi,
Many thanks for these ideas, since this posting was held back for moderation (it was my first one in this group) I asked the question on irc channel and got the tip: simply write a filter to collect the necessary data to a list which can be summed up."ktosiek" from irc channel wrote me the start of a filter which I modified to solve my problem :D

this is the Filter:

def multiget(dictionary, keys):
    return [int(dictionary[k]['xm_infos']['free_memory']) for k in keys]

which can then be used in a playbook like this:
    - name: show the sum
      debug: msg="{{ hostvars | multiget(keys=groups.Cluster)|sum }}"

The first Idea was to have the filter more generally to use it like this:
debug: msg="{{ hostvars | multiget(keys=groups.Cluster)|sum(attribute=xm_infos.free_memory) }}"
But the values inside the list must be casted to int and I had no other Idea than to do this inside the generation of the list.

 
Cheers
     Ulli

PS: I like ansible more and more especially the really cool and helpfull community ;-D
Reply all
Reply to author
Forward
0 new messages