2021年的答案

2021年的答案

我正在使用 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.dnfAnsible 模組訪問,但可以透過其別名ansible.builtin.shell或更直接地使用,甚至更明確地使用 來呼叫它。ansible.builtin.commandneeds-restarting -rdnf 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:

相關內容