with_items stat too verbose

60 views
Skip to first unread message

rjwagn...@gmail.com

unread,
Jan 28, 2019, 10:54:39 AM1/28/19
to Ansible Project
Hey all-

I'm using stat and with_items to check proper ownership of various files.  Is there any way to reduce the volume of output (i.e., eliminate everything in red, below)?

rowagn@localhost:~/data-platform/oracle/ansible/db12r2$ cat test.yml
---
- hosts: localhost
  tasks:
  - name: Stat filesystems
    stat: path="{{ item }}"
    with_items:
      - /dev
      - /home
    register: filesystems_stat

  - name: Confirming ownership of filesystems
    assert:
      that: "{{ item.stat.pw_name == 'root' }}"
    with_items: "{{ filesystems_stat.results }}"
    loop_control:
      label: "{{ item.item }}"

  - name: Stat filesystem no with_items
    stat: path="/dev"
    register: dev_stat

  - name: Confirming ownership of dev
    assert:
      that: "{{ dev_stat.stat.pw_name == 'root' }}"

rowagn@localhost:~/data-platform/oracle/ansible/db12r2$ ansible-playbook -i "localhost," -c local test.yml

PLAY [localhost] ***************************************************************

TASK [setup] *******************************************************************
ok: [localhost]

TASK [Stat filesystems] ********************************************************
ok: [localhost] => (item=/dev)
ok: [localhost] => (item=/home)

TASK [Confirming ownership of filesystems] *************************************
ok: [localhost] => (item=/dev) => {
    "changed": false,
    "item": {
        "changed": false,
        "invocation": {
            "module_args": {
                "checksum_algorithm": "sha1",
                "follow": false,
                "get_checksum": true,
                "get_md5": true,
                "mime": false,
                "path": "/dev"
            },
            "module_name": "stat"
        },
        "item": "/dev",
        "stat": {
            "atime": 1548686732.628008,
            "ctime": 1548686731.6280031,
            "dev": 6,
            "executable": true,
            "exists": true,
            "gid": 0,
            "gr_name": "root",
            "inode": 2,
            "isblk": false,
            "ischr": false,
            "isdir": true,
            "isfifo": false,
            "isgid": false,
            "islnk": false,
            "isreg": false,
            "issock": false,
            "isuid": false,
            "mode": "0755",
            "mtime": 1548686731.6280031,
            "nlink": 21,
            "path": "/dev",
            "pw_name": "root",
            "readable": true,
            "rgrp": true,
            "roth": true,
            "rusr": true,
            "size": 4340,
            "uid": 0,
            "wgrp": false,
            "woth": false,
            "writeable": false,
            "wusr": true,
            "xgrp": true,
            "xoth": true,
            "xusr": true
        }
    },

    "msg": "All assertions passed"
}
ok: [localhost] => (item=/home) => {
    "changed": false,
    "item": {
        "changed": false,
        "invocation": {
            "module_args": {
                "checksum_algorithm": "sha1",
                "follow": false,
                "get_checksum": true,
                "get_md5": true,
                "mime": false,
                "path": "/home"
            },
            "module_name": "stat"
        },
        "item": "/home",
        "stat": {
            "atime": 1548687317.493867,
            "ctime": 1519054783.2176335,
            "dev": 64512,
            "executable": true,
            "exists": true,
            "gid": 0,
            "gr_name": "root",
            "inode": 13631489,
            "isblk": false,
            "ischr": false,
            "isdir": true,
            "isfifo": false,
            "isgid": false,
            "islnk": false,
            "isreg": false,
            "issock": false,
            "isuid": false,
            "mode": "0755",
            "mtime": 1519054783.2176335,
            "nlink": 5,
            "path": "/home",
            "pw_name": "root",
            "readable": true,
            "rgrp": true,
            "roth": true,
            "rusr": true,
            "size": 4096,
            "uid": 0,
            "wgrp": false,
            "woth": false,
            "writeable": false,
            "wusr": true,
            "xgrp": true,
            "xoth": true,
            "xusr": true
        }
    },

    "msg": "All assertions passed"
}

TASK [Stat filesystem no with_items] *******************************************
ok: [localhost]

TASK [Confirming ownership of dev] *********************************************
ok: [localhost] => {
    "changed": false,
    "msg": "All assertions passed"
}

PLAY RECAP *********************************************************************
localhost                  : ok=5    changed=0    unreachable=0    failed=0  


Is there any way to avoid printing the entire stat dictionary for each item?  I have tried no_log: True, but that eliminates everything (i.e., so the output doesn't even include the path being tested):

TASK [Confirming ownership of filesystems] *************************************
ok: [localhost] => (item=(censored due to no_log)) => {"censored": "the output has been hidden due to the fact that 'no_log: true' was specified for this result"}
ok: [localhost] => (item=(censored due to no_log)) => {"censored": "the output has been hidden due to the fact that 'no_log: true' was specified for this result"}

Ideally, the output would be similar to that when not using with_items.  i.e.:

TASK [Confirming ownership of filesystems] *************************************
ok: [localhost] => (item=/dev) => {
    "changed": false,
    "msg": "All assertions passed"
}
ok: [localhost] => (item=/home) => {
    "changed": false,
    "msg": "All assertions passed"
}

Thanks for any advice.

Rob

Jonathan Lozada De La Matta

unread,
Jan 28, 2019, 12:31:43 PM1/28/19
to ansible...@googlegroups.com
using -v should be enough to show changes but, not the whole output.

--
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/7facb073-ba90-4af3-ab4b-b4cc830f47bd%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


--

Jonathan lozada de la matta

AUTOMATION PRACTICE



 

Felix Fontein

unread,
Jan 28, 2019, 2:11:57 PM1/28/19
to ansible...@googlegroups.com
Hi,

check out the label directive for loop_control:
https://docs.ansible.com/ansible/latest/user_guide/playbooks_loops.html#loop-control

Cheers,
Felix
> [...]

rjwagn...@gmail.com

unread,
Jan 30, 2019, 10:06:55 AM1/30/19
to Ansible Project
Hey Jonathan - thanks for the suggestion, but -v doesn't help.  If I include no_log: True, including -v just outputs the same:

TASK [Confirming ownership of filesystems] *************************************
ok: [localhost] => (item=(censored due to no_log)) => {"censored": "the output has been hidden due to the fact that 'no_log: true' was specified for this result"}
ok: [localhost] => (item=(censored due to no_log)) => {"censored": "the output has been hidden due to the fact that 'no_log: true' was specified for this result"}


Rob

rjwagn...@gmail.com

unread,
Jan 30, 2019, 10:09:00 AM1/30/19
to Ansible Project
Hey Felix - can you elaborate?  I'm already using:

loop_control:
      label: "{{ item.item }}"

As shown in my post.  It doesn't quench the output of the items.  Am I missing something?

Rob

Felix Fontein

unread,
Jan 30, 2019, 3:43:38 PM1/30/19
to ansible...@googlegroups.com
Hi Rob,

> Hey Felix - can you elaborate? I'm already using:
>
> loop_control:
> label: "{{ item.item }}"
>
> As shown in my post. It doesn't quench the output of the items. Am
> I missing something?

sorry, I guess I misunderstood something. The problem is that assert
always enables verbose output, so you cannot get rid of item
completely. What you can do is tidy up item so only the important
things are in there.

You could try something like

loop: |
{{ filesystems_stat.results | map(attribute='item')
| zip(filesystems_stat.results | map(attribute='stat.pw_name'))
| list }}

Then you should be able to access item.item via item.0 and
item.stat.pw_name via item.1, i.e. the rest of the task would be

assert:
that: item.1 == 'root'
loop_control:
label: "{{ item.0 }}"

(I haven't tested this, so it might contain bugs, but in principle that
should work. Note that the zip filter is Ansible specific, while the
map and list filters are generic Jinja2.)

(Also: with_items does the same as loop if you give it a simple list;
you should switch to loop in such cases, and stop using with_items if
not explicitly needed.)

Cheers,
Felix
--
Felix Fontein -- fe...@fontein.de -- https://felix.fontein.de/

Rob Wagner

unread,
Feb 6, 2019, 12:37:14 PM2/6/19
to ansible...@googlegroups.com
Thanks Felix.  That's a clever idea.  I tested it and I get:

ok: [localhost] => (item=/dev) => {
    "changed": false,
    "item": [
        "/dev",
        "root"
    ],
    "msg": "All assertions passed"
}
ok: [localhost] => (item=/home) => {
    "changed": false,
    "item": [
        "/home",
        "root"
    ],
    "msg": "All assertions passed"
}

I don't really understand why it needs to include "item" in the dict (i.e., after => ), since it's already present in the output (i.e., before => ), but this is better than the original.  Thanks again.

Rob

--
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/XRfVnH088fk/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.

Rob Wagner

unread,
Feb 8, 2019, 4:41:22 PM2/8/19
to ansible...@googlegroups.com
So I noticed that older versions (2.1.1) of ansible didn't have this problem, and I noticed that the verbosity of assert is caused by the following line in assert.py:

result['_ansible_verbose_always'] = True

If I comment that out, I get the quieter behavior I (and others, based on some reported github issues) am looking for.  So can anyone explain the purpose of the above line?  Why was it added to assert.py?  What is _ansible_verbose_always for?  Could I add another parameter to assert.py (maybe quiet) and, if set to True, then do not set result['_ansible_verbose_always'] to True?  I appreciate I'm getting into the weeds here, but I found it curious that assert got noisy in more recent versions.

Rob

Felix Fontein

unread,
Feb 9, 2019, 10:18:49 AM2/9/19
to ansible...@googlegroups.com
Hi Rob,

> So I noticed that older versions (2.1.1) of ansible didn't have this
> problem, and I noticed that the verbosity of assert is caused by the
> following line in assert.py:
>
> result['_ansible_verbose_always'] = True
>
> If I comment that out, I get the quieter behavior I (and others,
> based on some reported github issues) am looking for. So can anyone

I assume you are talking about this issue:
https://github.com/ansible/ansible/issues/27124

> explain the purpose of the above line? What is
> _ansible_verbose_always for?

That's easy: it makes the module behave as if -v is specified on the
ansible command line: it always produces verbose output when the assert
module is used.

> Why was it added to assert.py?

That's a good one. As you probably read in the issue, nobody remembers,
so it is unlikely someone suddenly can provide an explanation here :)

> Could I add another parameter to assert.py (maybe quiet) and, if set
> to True, then do not set result['_ansible_verbose_always'] to True?

Sure; that's essentially what @bcoca suggested here:
https://github.com/ansible/ansible/issues/27124#issuecomment-316855948

Feel free to create a PR which does that.

Cheers,
Felix

Rob Wagner

unread,
Feb 11, 2019, 2:00:16 PM2/11/19
to ansible...@googlegroups.com
Thanks Felix.  Working on a PR now.

Rob

--
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/XRfVnH088fk/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.

Thuan

unread,
Dec 19, 2020, 10:10:18 AM12/19/20
to Ansible Project
Hi,

I have the same issue.
I tried this method but it didn't work on Ansible 2.9.16.
Am I missing something ?


---
- hosts: localhost
  tasks:
  - name: Stat filesystems
    stat: path="{{ item }}"
    with_items:
      - /dev
      - /home
    register: filesystems_stat

  - name: Confirming ownership of filesystems
    loop: | 
          {{ filesystems_stat.results | map(attribute='item')
          | zip(filesystems_stat.results | map(attribute='stat.pw_name'))
          | list }}
    loop_control:
    label: "{{ item.item }}"
    

  - assert:
      that: item.1 == 'root'
    loop_control:
      label: "{{ item.0 }}"

Thuan

unread,
Dec 20, 2020, 9:46:02 PM12/20/20
to Ansible Project
I've figured it out.

Thanks for the o.p and the contributor solution !

---
- hosts: localhost
tasks:
- name: Stat filesystems
stat: path="{{ item }}"
with_items:
- /dev
- /home
register: filesystems_stat

- name: Confirming ownership of filesystems
loop: |
{{ filesystems_stat.results | map(attribute='item')
| zip(filesystems_stat.results | map(attribute='stat.pw_name'))
| list }}

assert:
that: item.1 == 'root'
loop_control:
label: "{{ item.0 }}"
Reply all
Reply to author
Forward
0 new messages