/vmlinuz
カーネルが に解決されない場合にホストを再起動する必要があるかどうかを確認するために、Ansible を使用していますuname -r
。
if
ただし、テスト マシンが再起動され、カーネルが同じカーネルに解決されているにもかかわらず、常に再起動が識別されるという条件があります。
if [ $(readlink -f /vmlinuz) != /boot/vmlinuz-$(uname -r) ]; then echo 'reboot'; else echo '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
この例では一致しないため、再起動が必要です。
文字列を比較するには 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
。これは、システム パッケージが前回の起動以降に更新されたかどうかを判断しますが、カーネルの変更だけに限定されるわけではありません。この動作は、カーネル バージョンとインストール済みパッケージを単純に比較するよりも優れていると言えます。
dnfneeds-restarting
モジュールは Ansible モジュール経由ではアクセスできませんが、またはそのエイリアス 経由で、または で直接的に、あるいは でより明示的にansible.builtin.dnf
呼び出すことができます。ansible.builtin.shell
ansible.builtin.command
needs-restarting -r
dnf needs-restarting -r
/usr/bin/dnf needs-restarting -r
この-r
フラグはルート権限を必要としないようで、再起動が必要かどうかを報告するだけです。再起動が必要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: