Need to check whether you need to reboot for a kernel update?
You could reliably determine the latest installed kernel version via the following rpm query:
rpm -q kernel --queryformat '%{installtime} %{version}-%{release}.%{arch}\n' | sort -n -k1 | tail -1 | cut -d ' ' -f 2
Sample output on RHEL 7:
3.10.0-229.11.1.el7.x86_64
Now just check whether the output of uname -r
matches:
3.10.0-229.1.2.el7.x86_64
In this example, it does not match and a reboot is required.
You could use test to compare the strings:
if [ "`rpm -q kernel --queryformat '%{installtime} %{version}-%{release}.%{arch}\n' | sort -n -k1 | tail -1 | cut -d ' ' -f 2`" = "`uname -r`" ]; then echo "latest kernel already booted."; else echo "new kernel. reboot required."; fi
Answer for 2021
As @kawing-chiu mentioned in their answer, dnf
now has a needs-restarting
module which does just what the question requires. It determines if system packages have been updated since last boot, although that is not limited to only kernel changes. This behavior is arguably better than simply comparing kernel version with installed packages.
The needs-restarting
dnf module is not accessible through the ansible.builtin.dnf
Ansible module, but it can be called through ansible.builtin.shell
or ansible.builtin.command
by its alias needs-restarting -r
, more directly with dnf needs-restarting -r
, or even more explicitly with /usr/bin/dnf needs-restarting -r
.
The -r
flag does not seem to require root privileges and simply reports if a reboot is necessary. The return code is 0
if no reboot is necessary and 1
if it is. Therefore, we should be able to use a task such as this one, which is adapted from the one suggested by Joël Cattin:
- name: Check if a reboot is required
ansible.builtin.command: needs-restarting -r
register: reg_reboot_required
ignore_errors: yes
failed_when: false
changed_when: reg_reboot_required.rc != 0
notify:
- Reboot server
You will also need a handler named, or listening to, Reboot server
to carry out the reboot task. Something like this will do the trick:
- name : Reboot server
ansible.builtin.reboot:
msg: "Reboot initiated by Ansible after OS update"
reboot_timeout: 3600
test_command: uptime
I hope this answer helps anyone who comes along seeking a solution to this problem.