0

I'am trying to automate the creation of the smart_[diskdevice] links to

/usr/share/munin/plugins/smart_

during the installation of the munin node via ansible.

The code here works partially, except there is no diskdevice to link on the target machine. Then I got a fatal failure with

{"msg": "with_dict expects a dict"}

I've review the ansible documentation and tried to search the problem in the web. For my understanding, the whole "file" directive should not be executed if the "when"-statement fails.

---
- name: Install Munin Node
  any_errors_fatal: true
  block:
...

# drives config
    - file:
        src: /usr/share/munin/plugins/smart_
        dest: /etc/munin/plugins/smart_{{ item.key }}
        state: link
      with_dict: "{{ ansible_devices }}"
      when: "item.value.host.startswith('SATA')"
      notify:
        - restart munin-node

On targets with a SATA-Drive, the code works. Drives like "sda" are found and the links are created. Loop- and other soft-Devices are ignored (as intended) Only on a Raspberry with no SATA-Drive at all i got the fatal failure.

Jasmir
  • 1
  • 3
  • What's in `ansible_devices`? Add `- debug: var=ansible_devices` before your "file" task. – Tomáš Pospíšek Aug 05 '19 at 18:19
  • very interesting: On my x86 targets, I got a tree-structure of the devices. But on the Raspi, I got all devices in one line. The line-wrap is missing. The System is a *4.15.0-1041-raspi2 #44-Ubuntu SMP PREEMPT aarch64 aarch64 aarch64 GNU/Linux* – Jasmir Aug 05 '19 at 18:32
  • If you think a comment adds value then you can up it. Others can see then whether the problem is potentially solved. – Tomáš Pospíšek Aug 05 '19 at 18:39

1 Answers1

0

You are using the with_dict option to set the loop. This sets the value of the item variable for each iteration as a dictionary with two keys:

  1. key: The name of the current key in the dict.
  2. value: The value of the existing key in the dict.

You are then running the when option that checks the item variable on each iteration. So check if that is the behavior you want.

Regarding your error, it is being thrown because for some reason, ansible_devices is not a dict as the error says. And Ansible checks for the validity of the with_dict type before resolving the when condition.

Check the following example:

---
- name: Diff test
  hosts: local
  connection: local
  gather_facts: no
  vars:
    dict:
      value: True
      name: "dict"
  tasks:
    - debug: var=item
      when: dict.value == False
      with_dict: '{{ dict }}'

    - debug: var=item
      when: dict.value == True
      with_dict: '{{ dict }}'

    - debug: var=item
      when: dict.value == False
      with_dict: "Not a dict"

The first two task will succeed because they have a valid dict on the with_dict option and a correct condition on the when option. The last one will fail because the with_dict value has the wrong type, even though the when condition resolves correctly and should guarantee to skip the task.

I hope it helps.

guzmonne
  • 2,490
  • 1
  • 16
  • 22