![2021 年答案](https://linux22.com/image/652939/2021%20%E5%B9%B4%E7%AD%94%E6%A1%88.png)
/vmlinuz
如果内核无法解析,我正在使用 Ansible 检查主机是否需要重新启动uname -r
。
尽管测试机器已经重新启动并且内核解析为同一个内核,但情况if
总是识别出重新启动:
如果 [ $(readlink -f /vmlinuz) != /boot/vmlinuz-$(uname -r) ]; 则回显“reboot”; 否则回显“no”; fi
- name: Check for reboot hint.
shell: if [ $(readlink -f /vmlinuz) != /boot/vmlinuz-$(uname -r) ]; then echo 'reboot'; else echo 'no'; fi
ignore_errors: true
register: reboot_hint
- name: Rebooting ...
command: shutdown -r now "Ansible kernel update applied"
async: 0
poll: 0
ignore_errors: true
when: kernelup|changed or reboot_hint.stdout.find("reboot") != -1
register: rebooting
- name: Wait for thing to reboot...
pause: seconds=45
when: rebooting|changed
答案1
您可以通过以下 rpm 查询可靠地确定最新安装的内核版本:
rpm -q kernel --queryformat '%{installtime} %{version}-%{release}.%{arch}\n' | sort -n -k1 | tail -1 | cut -d ' ' -f 2
RHEL 7 上的示例输出:
3.10.0-229.11.1.el7.x86_64
现在只需检查输出是否uname -r
匹配:
3.10.0-229.1.2.el7.x86_64
在这个例子中,它不匹配,需要重新启动。
您可以使用测试来比较字符串:
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
答案2
2021 年答案
正如@kawing-chiu 提到的他们的答案,dnf
现在有一个needs-restarting
模块可以满足这个问题的需要。它确定自上次启动以来系统软件包是否已更新,尽管这不仅限于内核更改。这种行为可以说比简单地将内核版本与已安装的软件包进行比较要好。
dnf模块needs-restarting
无法通过ansible.builtin.dnf
Ansible 模块访问,但可以通过ansible.builtin.shell
或其ansible.builtin.command
别名进行调用needs-restarting -r
,更直接地使用dnf needs-restarting -r
,甚至更明确地使用/usr/bin/dnf needs-restarting -r
。
该-r
标志似乎不需要 root 权限,只是报告是否需要重新启动。返回代码是0
如果不需要重新启动,1
则返回。因此,我们应该能够使用这样的任务,它改编自若埃尔·卡丹:
- 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
您还需要一个命名或监听的处理程序Reboot server
来执行重启任务。类似下面的代码就可以了:
- name : Reboot server
ansible.builtin.reboot:
msg: "Reboot initiated by Ansible after OS update"
reboot_timeout: 3600
test_command: uptime
我希望这个答案能够帮助任何寻求解决此问题的人。
答案3
旧线程 - 但这帮助我整理了这个可能对某些人有帮助的快速 ansible 脚本。
---
- hosts: allhosts
gather_facts: False
tasks:
- name: check latest kernel installed
shell: rpm -q kernel --queryformat '%{installtime} %{version}-%{release}.%{arch}\n' | sort -n -k1 | tail -1 | cut -d ' ' -f 2
register: kernel_installed_latest
- name: Check running kernel version
shell: uname -r
register: kernel_version
- fail:
msg: "latest kernel version {{kernel_installed_latest.stdout}} doesnt match running kernel {{kernel_version.stdout}}"
when: (kernel_installed_latest.stdout != kernel_version.stdout)
答案4
另一种选择是单独进行内核更新,并在需要内核更新时触发处理程序以重新启动系统。
tasks
- name: Upgrade all packages, excluding kernel
ansible.builtin.yum:
name: '*'
state: latest
exclude: kernel*
- name: Upgrade kernel
ansible.builtin.yum:
name: 'kernel*'
state: latest
notify: restart host
handlers:
- name: restart host
ansible.builtin.reboot: