Estoy usando Ansible para verificar los hosts si es necesario reiniciarlos si el /vmlinuz
kernel no resuelve uname -r
.
La if
condición es, aunque siempre se identifica un reinicio, aunque la máquina de prueba se haya reiniciado y el kernel se esté resolviendo en el mismo kernel:
if [ $(readlink -f /vmlinuz) != /boot/vmlinuz-$(uname -r) ]; luego haga eco de 'reiniciar'; de lo contrario, haga eco de '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
Respuesta1
Puede determinar de manera confiable la última versión del kernel instalada mediante la siguiente consulta rpm:
rpm -q kernel --queryformat '%{installtime} %{version}-%{release}.%{arch}\n' | sort -n -k1 | tail -1 | cut -d ' ' -f 2
Salida de muestra en RHEL 7:
3.10.0-229.11.1.el7.x86_64
Ahora sólo comprueba si la salida de uname -r
coincidencias:
3.10.0-229.1.2.el7.x86_64
En este ejemplo, no coincide y es necesario reiniciar.
Podrías usar test para comparar las cadenas:
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
Respuesta2
Respuesta para 2021
Como @kawing-chiu mencionó ensu respuesta, dnf
ahora tiene un needs-restarting
módulo que hace exactamente lo que requiere la pregunta. Determina si los paquetes del sistema se han actualizado desde el último arranque, aunque eso no se limita únicamente a los cambios del kernel. Podría decirse que este comportamiento es mejor que simplemente comparar la versión del kernel con los paquetes instalados.
needs-restarting
No se puede acceder al módulo dnf a través del ansible.builtin.dnf
módulo Ansible, pero se puede llamar a través ansible.builtin.shell
de ansible.builtin.command
su alias needs-restarting -r
, más directamente con dnf needs-restarting -r
o incluso más explícitamente con /usr/bin/dnf needs-restarting -r
.
La -r
bandera no parece requerir privilegios de root y simplemente informa si es necesario reiniciar. El código de retorno es 0
si no es necesario reiniciar y 1
si lo es. Por lo tanto, deberíamos poder utilizar una tarea como esta, que está adaptada de la sugerida porJoel 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
También necesitará un controlador nombrado o escuchando Reboot server
para llevar a cabo la tarea de reinicio. Algo como esto funcionará:
- name : Reboot server
ansible.builtin.reboot:
msg: "Reboot initiated by Ansible after OS update"
reboot_timeout: 3600
test_command: uptime
Espero que esta respuesta ayude a cualquiera que venga buscando una solución a este problema.
Respuesta3
Hilo ANTIGUO, pero esto me ayudó a crear este script ansible rápido que podría ayudar a alguien.
---
- 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)
Respuesta4
Otra alternativa es realizar las actualizaciones del kernel por separado y activar un controlador para reiniciar el sistema si se requiere la actualización del kernel.
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: