我正在使用 Ansible 來檢查主機是否需要在內核/vmlinuz
未解析為uname -r
.
情況if
是,儘管測試機器已重新啟動並且內核正在解析為相同的內核,但始終識別出重新啟動:
if [ $(readlink -f /vmlinuz) != /boot/vmlinuz-$(uname -r) ];然後回顯“重新啟動”;否則回顯「不」;菲
- 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
在此範例中,它不匹配,需要重新啟動。
您可以使用 test 來比較字串:
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: