Sum a list of items received

697 views
Skip to first unread message

harry devine

unread,
Feb 27, 2020, 9:36:20 AM2/27/20
to Ansible Project
I'm using the gluster_heal_info module to check the heal status of a gluster volume.  What I'd like to do is gather the "no_of_entries" parameter, sum them up, and it if it is 0, move to the next step of stopping gluster on that server, update it, and restart the service.  The playbook below is my initial test to see how to grab that information.  It is giving me the following error:

 [root@test-server ~]#ansible-playbook gluster_heal_info.yml --limit storage1.tc.secure-ose.faa.gov -K
BECOME password:

PLAY [gluster] *************************************************************************************************************************************

TASK [Find out the healing status of /home] ********************************************************************************************************
ok: [gluster1]

TASK [set_fact] ************************************************************************************************************************************
fatal: [gluster1]: FAILED! => {"msg": "Unexpected templating type error occurred on ({{ home_heal_status.glusterfs.heal_info | sum(attribute='no_of_entries', start=[]) }}): can only concatenate list (not \"AnsibleUnsafeText\") to list"}


I'm not too familiar with jinja2 templates yet, so I'm sure I'm not doing something correct.  Can anyone point me in the right direction?

Thanks,
Harry

---
- hosts: gluster
  become: yes
  become_method: sudo
  gather_facts: no

  tasks:

  - name: Find out the healing status of /home
    gluster_heal_info:
      name: home
      status_filter: self-heal
    register: home_heal_status

  - set_fact:
      home_heal_entries: "{{ home_heal_status.glusterfs.heal_info | sum(attribute='no_of_entries', start=[]) }}"
  - debug:
      msg: "Heal entries: {{ home_heal_entries }}"

Daniel Whitley

unread,
Feb 27, 2020, 12:49:02 PM2/27/20
to ansible...@googlegroups.com
Hey Harry-
I saw this over my lunch break and thought I'd ask if it really matters (meaning, do you use it later or something) what the count/sum is or if you just want to wait until something is true (such as the number of "heals" is 0).  If the count doesn't really matter, I wonder if you could take advantage of until in your "Find out the healing status of /home" task?  It looks like the gluster_heal_info module returns a list of files in "heal_info" so you may just want to wait "until" that list is empty before moving on to the next task?  I've not tried this nor ever used the module.  I also realize it doesn't address the question you asked, but you should be used to that from me at this point. :)
-Daniel


--

harry devine

unread,
Feb 27, 2020, 1:44:39 PM2/27/20
to ansible...@googlegroups.com
Hey Daniel!  This stem from ticket #02582900. Since the stance from Support is “we don’t debug playbooks”, I care here. 

Their suggestion was to make sure that no healing operation was going on, stop Gluster, do the “yum update “, then restart Gluster & move to the next server. 

So what I’m trying to accomplish is start with server1, wait for any healing operations on our 3 volumes to finish, stop/update/start then move to the next. I’m sure this will lead to a “workflow template” discussion/approach, but right now this is my starting point. 

Thanks,
Harry

--
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 view this discussion on the web visit https://groups.google.com/d/msgid/ansible-project/CA%2BM63kcQw_UTUMW%2BmLXd0uNv3Bgowfdy9yP_v%2B55yW9cKkKN6A%40mail.gmail.com.

harry devine

unread,
Mar 2, 2020, 9:29:53 AM3/2/20
to Ansible Project
To unsubscribe from this group and stop receiving emails from it, send an email to ansible-project+unsubscribe@googlegroups.com.


So to follow up on this:  I looked at this further, and while the gluster_heal_info module DOES return a heal_info list, its not a list of files.  It returns the value of every brick (brick name, number of entries, and stattus):

"heal_info": [
                {
                    "brick": " server1:/gluster_bricks/brick3/1",
                    "no_of_entries": "0",
                    "status": "Connected"
                },
                {
                    "brick": " server2:/gluster_bricks/brick4/1",
                    "no_of_entries": "0",
                    "status": "Connected"
                }
]

So what I think I need to do is to get the "no_of_entries" value from every brick and sum them up.  If the sum is zero, I can continue on.  If the sum is greater than zero, then there is a heal in process, and I need to wait until that is finished before continuing.  That's the part I'm getting stuck on.  Also, if you look at the heal_info list, the bricks are ALL bricks associated with the gluster volume, which is across all gluster servers.  So would it be safe to assume that if the sum is zero, then there is no healing occuring on any server, and the continue-on procedure is to stop gluster on all servers, update them, then restart gluster?

Thanks,
Harry
 

Daniel Whitley

unread,
Mar 2, 2020, 11:49:09 AM3/2/20
to ansible...@googlegroups.com
Hey Harry-
That's insightful information about heal_info actually being a list of dicts.  With that being said, while you CAN create a sum (one such way is something like {{ heal_info | map(attribute='no_of_entries') | map('int') | sum() }}), I still question if that is truly necessary.  It sounds to me as if all you care about is waiting until no_of_entries is 0 for every brick.  Using your initial task, I wonder if this untested pseudo-code could be modified for your needs:

  - name: Find out the healing status of /home
    gluster_heal_info:
      name: home
      status_filter: self-heal
    register: home_heal_status
    until: home_heal_status.glusterfs.heal_info | selectattr('no_of_entries','ne','0') | list | count == 0
    retries: 5
    delay: 10

Hopefully this is helpful.
-Daniel

To unsubscribe from this group and stop receiving emails from it, send an email to ansible-proje...@googlegroups.com.


So to follow up on this:  I looked at this further, and while the gluster_heal_info module DOES return a heal_info list, its not a list of files.  It returns the value of every brick (brick name, number of entries, and stattus):

"heal_info": [
                {
                    "brick": " server1:/gluster_bricks/brick3/1",
                    "no_of_entries": "0",
                    "status": "Connected"
                },
                {
                    "brick": " server2:/gluster_bricks/brick4/1",
                    "no_of_entries": "0",
                    "status": "Connected"
                }
]

So what I think I need to do is to get the "no_of_entries" value from every brick and sum them up.  If the sum is zero, I can continue on.  If the sum is greater than zero, then there is a heal in process, and I need to wait until that is finished before continuing.  That's the part I'm getting stuck on.  Also, if you look at the heal_info list, the bricks are ALL bricks associated with the gluster volume, which is across all gluster servers.  So would it be safe to assume that if the sum is zero, then there is no healing occuring on any server, and the continue-on procedure is to stop gluster on all servers, update them, then restart gluster?

Thanks,
Harry
 

--
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 view this discussion on the web visit https://groups.google.com/d/msgid/ansible-project/70668aff-e0fe-4f4f-8606-ffc1cc273f52%40googlegroups.com.

harry devine

unread,
Mar 2, 2020, 4:26:28 PM3/2/20
to Ansible Project
Is there a "not equal to" jinja filter?  All of the documentation I find shows there's an 'equalto' but I can't seem to find any "no equalto" equivalent.  Even a greater than would work but I can't find anything like that either.

Harry
To unsubscribe from this group and stop receiving emails from it, send an email to ansible...@googlegroups.com.


So to follow up on this:  I looked at this further, and while the gluster_heal_info module DOES return a heal_info list, its not a list of files.  It returns the value of every brick (brick name, number of entries, and stattus):

"heal_info": [
                {
                    "brick": " server1:/gluster_bricks/brick3/1",
                    "no_of_entries": "0",
                    "status": "Connected"
                },
                {
                    "brick": " server2:/gluster_bricks/brick4/1",
                    "no_of_entries": "0",
                    "status": "Connected"
                }
]

So what I think I need to do is to get the "no_of_entries" value from every brick and sum them up.  If the sum is zero, I can continue on.  If the sum is greater than zero, then there is a heal in process, and I need to wait until that is finished before continuing.  That's the part I'm getting stuck on.  Also, if you look at the heal_info list, the bricks are ALL bricks associated with the gluster volume, which is across all gluster servers.  So would it be safe to assume that if the sum is zero, then there is no healing occuring on any server, and the continue-on procedure is to stop gluster on all servers, update them, then restart gluster?

Thanks,
Harry
 

--
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...@googlegroups.com.

Kai Stian Olstad

unread,
Mar 2, 2020, 4:41:08 PM3/2/20
to ansible...@googlegroups.com
On Mon, Mar 02, 2020 at 01:26:28PM -0800, harry devine wrote:
> Is there a "not equal to" jinja filter? All of the documentation I find
> shows there's an 'equalto' but I can't seem to find any "no equalto"
> equivalent. Even a greater than would work but I can't find anything like
> that either.

There is not a "not equal to" filter or an "equalto" filer.
But you have a "not equal to" _test_
https://jinja.palletsprojects.com/en/2.10.x/templates/#ne
As used in Daniels example

and an "equal to" _test_
https://jinja.palletsprojects.com/en/2.10.x/templates/#eq

Greater then _test_ is called gt
https://jinja.palletsprojects.com/en/2.10.x/templates/#gt

All the _tests_ is here
https://jinja.palletsprojects.com/en/2.10.x/templates/#list-of-builtin-tests

--
Kai Stian Olstad

harry devine

unread,
Mar 3, 2020, 7:53:59 AM3/3/20
to Ansible Project
Well, I'm obviously completely misunderstanding something.  Here's what the playbook looks like:

---
- hosts: gluster
  become: yes
  become_method: sudo
  gather_facts: no

  tasks:

  - name: Find out the healing status of /home
    gluster_heal_info:
      name: home
      status_filter: self-heal
    register: home_heal_status
    until: home_heal_status.glusterfs.heal_info | selectattr('no_of_entries','ne','0') | list | count == 0
    retries: 5
    delay: 10

  - name: Test if we can continue
    ping:

And here's the error I get:

fatal: [server1]: FAILED! => {"msg": "The conditional check 'home_heal_status.glusterfs.heal_info | selectattr('no_of_entries','ne','0') | list | count == 0' failed. The error was: no test named 'ne'"}

Sure looks like 'ne' doesn't exist to me!

Harry

Felix Fontein

unread,
Mar 3, 2020, 8:38:23 AM3/3/20
to ansible...@googlegroups.com
Hi,

> Well, I'm obviously completely misunderstanding something. Here's
> what the playbook looks like:
> [...]
> fatal: [server1]: FAILED! => {"msg": "The conditional check
> 'home_heal_status.glusterfs.heal_info |
> selectattr('no_of_entries','ne','0') | list | count == 0' failed. The
> error was: no test named 'ne'"}
>
> Sure looks like 'ne' doesn't exist to me!

you might have an older Jinja2 version installed. IIRC the 'ne' test
was not present in every version.

Cheers,
Felix



harry devine

unread,
Mar 3, 2020, 9:14:34 AM3/3/20
to Ansible Project
My system is RHEL 7.7.  The version of jinja2 is 2.7.2 and there isn't a newer version available:

 [root@server1 ~]#rpm -qa python-jinja2
python-jinja2-2.7.2-4.el7.noarch

Harry

harry devine

unread,
Mar 3, 2020, 9:31:28 AM3/3/20
to Ansible Project
I did a "pip install -U jinja2", then "pip install jinja2", and it appears to have installed 2.11.1.  Now the playbook runs, so that must've been it.  

Now I need to figure out how to check the other 2 gluster volumes at the same time, then do each gluster server 1 at a time.  But that's another topic that I won't go into here.  Yet.

Thanks,
Harry
Reply all
Reply to author
Forward
0 new messages