1

I am trying to update our RHEL7 machine using an Ansible Playbook, that, if the kernel has been updated, automatically reboots the machine.

This is what I came up with:

---
- hosts:  server1
  become: yes
  tasks:
    - name: YUM Update
      yum:
        name:  "*"
        state: latest
      register: yum_updates

    - debug:
        var: yum_updates.changes.updated

    - name: Reboot server1
      reboot:
      when: '"kernel" in yum_updates.changes.updated'
...

Of course the update works so far, but I can't find a way of evaluating the output variable the way I need it. That's the output:

PLAY [server1] *********************************************************************************************************************************************************************************

TASK [Gathering Facts] *********************************************************************************************************************************************************************************
ok: [server1]

TASK [YUM Update] **************************************************************************************************************************************************************************************
changed: [server1]

TASK [debug] *******************************************************************************************************************************************************************************************
ok: [de-agb1-smba01t] => {
    "yum_updates.changes.updated": [
        [
            "kernel-headers", 
            "3.10.0-1062.4.3.el7.x86_64 from rhel-7-server-rpms"
        ], 
        [
            "kernel", 
            "3.10.0-1062.4.3.el7.x86_64 from rhel-7-server-rpms"
        ], 
        [
            "sudo", 
            "1.8.23-4.el7_7.1.x86_64 from rhel-7-server-rpms"
        ], 
        [
            "bpftool", 
            "3.10.0-1062.4.3.el7.x86_64 from rhel-7-server-rpms"
        ], 
        [
            "python-perf", 
            "3.10.0-1062.4.3.el7.x86_64 from rhel-7-server-rpms"
        ], 
        [
            "kernel-tools-libs", 
            "3.10.0-1062.4.3.el7.x86_64 from rhel-7-server-rpms"
        ], 
        [
            "kernel-devel", 
            "3.10.0-1062.4.3.el7.x86_64 from rhel-7-server-rpms"
        ], 
        [
            "microcode_ctl", 
            "2:2.1-53.3.el7_7.x86_64 from rhel-7-server-rpms"
        ], 
        [
            "SDL", 
            "1.2.15-14.el7_7.x86_64 from rhel-7-server-rpms"
        ], 
        [
            "kernel-tools", 
            "3.10.0-1062.4.3.el7.x86_64 from rhel-7-server-rpms"
        ], 
        [
            "perf", 
            "3.10.0-1062.4.3.el7.x86_64 from rhel-7-server-rpms"
        ]
    ]
}

TASK [Reboot server1] **************************************************************************************************************************************************************************************
skipping: [server1]

PLAY RECAP *********************************************************************************************************************************************************************************************
server1            : ok=3    changed=1    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0   

How could the when Condition look like, that it would find the word "kernel"?

Any idea?

1

A simple solution is to flatten the lists, select items that match the pattern and test if any item met the condition.

when: yum_updates.changes.updated|flatten|select('regex', '^kernel$') is any
1
  • Hello Vladimir, that was, what I was looking for! Thanks a lot! Nov 29 '19 at 21:50
1

Using the flatten filter as shown in the accepted answer https://unix.stackexchange.com/a/554727/307127 co-mingles the package names and versions into a single list. Although this is unlikely to cause any issues, it is not a clean as it could be.

Instead, you could write the test for rebooting as
when: dict((yum_updates.changes|default(dict())).updated|default([])).kernel is defined

This converts the list of changed packages and versions to a dictionary (with package names as key and version as value), and then tests to see if the dictionary contains the key "kernel". Note the use of the "default" filter in two places to cover off edge cases such as when no packages are updated. This is necessary because when no packages are updated, the "changes" key is not present in the registered variable (i.e. "yum_updates.changes" does not exist).

0

You have a list (yum.updates.changes.updated) of which each item is a list of two items (package name and version). A simple when condition that would only match for the kernel package would look like:

---
- debug:
    msg: "{{ item.0 }} was updated to version {{ item.1 }}"
  when: item.0 == "kernel"
  loop: "{{ yum_updates.changes.updated }}"

Given your example data, this task would output:

TASK [debug] *****************************************************************************************************************************************************************
skipping: [localhost] => (item=['kernel-headers', '3.10.0-1062.4.3.el7.x86_64 from rhel-7-server-rpms'])
ok: [localhost] => (item=['kernel', '3.10.0-1062.4.3.el7.x86_64 from rhel-7-server-rpms']) => {
    "msg": "kernel was updated to version 3.10.0-1062.4.3.el7.x86_64 from rhel-7-server-rpms"
}
skipping: [localhost] => (item=['sudo', '1.8.23-4.el7_7.1.x86_64 from rhel-7-server-rpms'])
skipping: [localhost] => (item=['bpftool', '3.10.0-1062.4.3.el7.x86_64 from rhel-7-server-rpms'])
skipping: [localhost] => (item=['python-perf', '3.10.0-1062.4.3.el7.x86_64 from rhel-7-server-rpms'])
skipping: [localhost] => (item=['kernel-tools-libs', '3.10.0-1062.4.3.el7.x86_64 from rhel-7-server-rpms'])
skipping: [localhost] => (item=['kernel-devel', '3.10.0-1062.4.3.el7.x86_64 from rhel-7-server-rpms'])
skipping: [localhost] => (item=['microcode_ctl', '2:2.1-53.3.el7_7.x86_64 from rhel-7-server-rpms'])
skipping: [localhost] => (item=['SDL', '1.2.15-14.el7_7.x86_64 from rhel-7-server-rpms'])
skipping: [localhost] => (item=['kernel-tools', '3.10.0-1062.4.3.el7.x86_64 from rhel-7-server-rpms'])
skipping: [localhost] => (item=['perf', '3.10.0-1062.4.3.el7.x86_64 from rhel-7-server-rpms'])
1
  • Hello larsks, thanks a lot for your effort! For this scenario it would even work, since there's only one kernel package of course, it would only reboot once… But the answer of Vladimir seems to hit the point better, since the outcome is only true or false instead of 0, 1 or more… But again, I appreciate your input and I used your Idea already in a different playbook :) Thank you Nov 29 '19 at 22:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.