- name: Patching | Initialize RedHat report state ansible.builtin.set_fact: _aim_patch_action_failed: false _aim_patch_pre_reboot_performed: false _aim_patch_post_reboot_performed: false _aim_patch_preexisting_reboot_required: false - name: Patching | Detect existing needs-restarting command ansible.builtin.command: argv: - /bin/sh - -c - command -v needs-restarting register: _aim_needs_restarting_available changed_when: false failed_when: false check_mode: false - name: Patching | Detect pending RedHat reboot before patching become: true ansible.builtin.command: cmd: needs-restarting -r register: _aim_patch_pre_reboot_probe changed_when: false failed_when: _aim_patch_pre_reboot_probe.rc not in [0, 1] when: _aim_needs_restarting_available.rc == 0 - name: Patching | Record pre-existing RedHat reboot state ansible.builtin.set_fact: _aim_patch_preexisting_reboot_required: >- {{ (_aim_needs_restarting_available.rc == 0) and (_aim_patch_pre_reboot_probe.rc | default(0) == 1) }} - name: Patching | Publish blocked RedHat result when reboot is deferred when: - _aim_patch_preexisting_reboot_required | bool - not (os_patching_reboot | bool) block: - name: Patching | Build blocked RedHat patch report ansible.builtin.set_fact: _aim_patch_report: >- {{ 'redhat' | aim_report_patch_blocked(ansible_check_mode, os_patching_reboot_delay_minutes | int) }} - name: AIM | Publish blocked operation result ansible.builtin.set_stats: per_host: true aggregate: false data: aim_output: protocol: aim_output_v1 schema: patch_summary_v1 data: '{{ _aim_patch_report }}' - name: Patching | Require reboot before continuing RedHat patching ansible.builtin.fail: msg: >- A reboot is already pending from a previous update or installation. Reboot the host first, or rerun with "Reboot when required" enabled. No new package upgrade was started by this run. - name: Patching | Clear pre-existing RedHat reboot before patching become: true ansible.builtin.reboot: msg: '{{ os_patching_reboot_message }}' pre_reboot_delay: '{{ (os_patching_reboot_delay_minutes | int) * 60 }}' reboot_timeout: '{{ os_patching_reboot_timeout | int }}' register: _aim_patch_pre_reboot when: - _aim_patch_preexisting_reboot_required | bool - os_patching_reboot | bool - not ansible_check_mode - name: Patching | Record pre-patch RedHat reboot ansible.builtin.set_fact: _aim_patch_pre_reboot_performed: '{{ _aim_patch_pre_reboot.rebooted | default(false) | bool }}' - name: Patching | Collect installed package facts before operation ansible.builtin.package_facts: manager: auto - name: Patching | Snapshot installed package facts before operation ansible.builtin.set_fact: _aim_packages_before: '{{ ansible_facts.packages | default({}) }}' - name: Patching | Apply native RedHat updates block: - name: Update RHEL-based host become: true ansible.builtin.dnf: name: '*' state: latest update_only: true - name: Ensure needs-restarting binary is present (yum-utils) become: true ansible.builtin.dnf: name: yum-utils state: present - name: Check if RHEL-based host requires reboot become: true ansible.builtin.command: cmd: needs-restarting -r register: os_patching_reboot_required changed_when: false failed_when: os_patching_reboot_required.rc not in [0, 1] rescue: - name: Patching | Retain failed action for reporting ansible.builtin.set_fact: _aim_patch_action_failed: true - name: Patching | Reboot RedHat host after updates when required become: true ansible.builtin.reboot: msg: '{{ os_patching_reboot_message }}' pre_reboot_delay: '{{ (os_patching_reboot_delay_minutes | int) * 60 }}' reboot_timeout: '{{ os_patching_reboot_timeout | int }}' register: _aim_patch_post_reboot when: - os_patching_reboot | bool - not ansible_check_mode - os_patching_reboot_required.rc | default(0) == 1 - name: Patching | Record post-update RedHat reboot ansible.builtin.set_fact: _aim_patch_post_reboot_performed: '{{ _aim_patch_post_reboot.rebooted | default(false) | bool }}' - name: Patching | Collect installed package facts after operation ansible.builtin.package_facts: manager: auto - name: Patching | Snapshot installed package facts after operation ansible.builtin.set_fact: _aim_packages_after: '{{ ansible_facts.packages | default({}) }}' - name: Patching | Compare package database snapshots ansible.builtin.set_fact: _aim_patch_report: >- {{ _aim_packages_before | aim_report_patch_linux( _aim_packages_after, 'redhat', ansible_check_mode, not _aim_patch_action_failed, (os_patching_reboot_required.rc == 1) if os_patching_reboot_required.rc is defined else none, (_aim_patch_pre_reboot_performed | bool) or (_aim_patch_post_reboot_performed | bool), _aim_patch_preexisting_reboot_required | bool, os_patching_reboot | bool, os_patching_reboot_delay_minutes | int ) }} - name: Patching | Package change summary ansible.builtin.debug: msg: '{{ _aim_patch_report }}' - name: AIM | Publish operation result ansible.builtin.set_stats: per_host: true aggregate: false data: aim_output: protocol: aim_output_v1 schema: patch_summary_v1 data: '{{ _aim_patch_report }}' - name: Patching | Preserve native operation failure ansible.builtin.fail: msg: >- The native RedHat patch operation failed. Available observed package changes and reboot state are in the structured result. If a reboot is reported as required, reboot before retrying. when: _aim_patch_action_failed | bool