Resposta para 2021

Resposta para 2021

Estou usando o Ansible para verificar os hosts se eles precisam ser reinicializados se o /vmlinuzkernel não resolver uname -r.

A ifcondição é sempre identificar uma reinicialização, mesmo que a máquina de teste tenha sido reinicializada e o kernel esteja resolvendo para o mesmo kernel:

if [ $(readlink -f /vmlinuz) != /boot/vmlinuz-$(uname -r) ]; então echo 'reboot'; senão ecoe 'não'; 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

Responder1

Você pode determinar com segurança a versão mais recente do kernel instalado por meio da seguinte consulta rpm:

rpm -q kernel --queryformat '%{installtime} %{version}-%{release}.%{arch}\n' | sort -n -k1 | tail -1 | cut -d ' ' -f 2

Exemplo de saída no RHEL 7:

3.10.0-229.11.1.el7.x86_64

Agora é só verificar se a saída de uname -rcorresponde:

3.10.0-229.1.2.el7.x86_64

Neste exemplo, ele não corresponde e é necessária uma reinicialização.

Você poderia usar test para comparar as strings:

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

Responder2

Resposta para 2021

Como @kawing-chiu mencionou ema resposta deles, dnfagora possui um needs-restartingmódulo que faz exatamente o que a pergunta exige. Ele determina se os pacotes do sistema foram atualizados desde a última inicialização, embora isso não se limite apenas às alterações do kernel. Este comportamento é indiscutivelmente melhor do que simplesmente comparar a versão do kernel com os pacotes instalados.

O needs-restartingmódulo dnf não é acessível através do ansible.builtin.dnfmódulo Ansible, mas pode ser chamado através ansible.builtin.shellou ansible.builtin.commandpelo seu alias needs-restarting -r, mais diretamente com dnf needs-restarting -r, ou ainda mais explicitamente com /usr/bin/dnf needs-restarting -r.

O -rsinalizador não parece exigir privilégios de root e simplesmente informa se uma reinicialização é necessária. O código de retorno é 0se nenhuma reinicialização for necessária e 1se for. Portanto, deveríamos ser capazes de utilizar uma tarefa como esta, que é adaptada daquela 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 

Você também precisará de um manipulador nomeado ou de escuta Reboot serverpara realizar a tarefa de reinicialização. Algo assim resolverá o problema:

- name : Reboot server
  ansible.builtin.reboot:
    msg: "Reboot initiated by Ansible after OS update"
    reboot_timeout: 3600
    test_command: uptime

Espero que esta resposta ajude quem procura uma solução para este problema.

Responder3

Tópico ANTIGO - mas isso me ajudou a montar esse script rápido e ansible que pode ajudar alguém.

---
- 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)

Responder4

Outra alternativa é fazer atualizações do kernel separadamente e acionar um manipulador para reiniciar o sistema se a atualização do kernel for necessária.

  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:

informação relacionada